class CartesianService
{
public static function cartezianIterator($inputArray)
{
$maximumPosition = array_map('count', $inputArray);
$position = array_pad([], count($inputArray), 0);
while (false !== ($item = self::buildItemAtPosition($inputArray, $position))) {
yield $item;
$position = self::incrementPosition($position, $maximumPosition);
}
}
private static function buildItemAtPosition($inputArray, $positions)
{
if ($positions[0] >= count($inputArray[0])) {
return false;
}
$item = [];
foreach ($inputArray as $rowIndex => $row) {
$position = $positions[$rowIndex];
$item[] = $row[$position];
}
return $item;
}
private static function incrementPosition($position, $maximumPosition)
{
$digitToIncrement = count($position) - 1;
do {
++$position[$digitToIncrement];
if ($position[$digitToIncrement] < $maximumPosition[$digitToIncrement] || 0 === $digitToIncrement) {
//no overflow
break;
}
//overflow, reset to zero and increment parent digit
$position[$digitToIncrement] = 0;
--$digitToIncrement;
} while ($digitToIncrement >= 0);
return $position;
}
}
使用
foreach (CartesianService::cartezianIterator(array_values($cartesian_arr)) as $item) {
var_dump($item);
}