Я пытаюсь найти все комбинации элементов в нескольких массивах. Количество массивов является случайным (это может быть 2, 3, 4, 5 …). Количество элементов в каждом массиве тоже случайное …
Например, у меня есть 3 массива:
$arrayA = array('A1','A2','A3'); $arrayB = array('B1','B2','B3'); $arrayC = array('C1','C2');
Я хотел бы создать массив с 3 x 3 x 2 = 18 комбинациями:
Проблема заключается в создании функции с переменным количеством исходных массивов …
Здесь рекурсивное решение:
function combinations($arrays, $i = 0) { if (!isset($arrays[$i])) { return array(); } if ($i == count($arrays) - 1) { return $arrays[$i]; } // get combinations from subsequent arrays $tmp = combinations($arrays, $i + 1); $result = array(); // concat each array from tmp with each element from $arrays[$i] foreach ($arrays[$i] as $v) { foreach ($tmp as $t) { $result[] = is_array($t) ? array_merge(array($v), $t) : array($v, $t); } } return $result; } print_r( combinations( array( array('A1','A2','A3'), array('B1','B2','B3'), array('C1','C2') ) ) );
Это декартовый продукт, и я просто задал тот же вопрос не так давно . Вот алгоритм, который размещен на веб-сайте PHP .
function array_cartesian_product($arrays) { $result = array(); $arrays = array_values($arrays); $sizeIn = sizeof($arrays); $size = $sizeIn > 0 ? 1 : 0; foreach ($arrays as $array) $size = $size * sizeof($array); for ($i = 0; $i < $size; $i ++) { $result[$i] = array(); for ($j = 0; $j < $sizeIn; $j ++) array_push($result[$i], current($arrays[$j])); for ($j = ($sizeIn -1); $j >= 0; $j --) { if (next($arrays[$j])) break; elseif (isset ($arrays[$j])) reset($arrays[$j]); } } return $result; }
Этот код, кроме простоты, получает все комбинации из нескольких массивов и сохраняет ключи.
function get_combinations($arrays) { $result = array(array()); foreach ($arrays as $property => $property_values) { $tmp = array(); foreach ($result as $result_item) { foreach ($property_values as $property_key => $property_value) { $tmp[] = $result_item + array($property_key => $property_value); } } $result = $tmp; } return $result; }
Exemple:
Array ( Array ( '1' => 'White', '2' => 'Green', '3' => 'Blue' ), Array ( '4' =>' Small', '5' => 'Big' ) )
Вернется:
Array ( [0] => Array ( [1] => White [4] => Small ) [1] => Array ( [1] => White [5] => Big ) [2] => Array ( [2] => Green [4] => Small ) [3] => Array ( [2] => Green [5] => Big ) [4] => Array ( [3] => Blue [4] => Small ) [5] => Array ( [3] => Blue [5] => Big ) )
Я знаю, что этот вопрос старый, но сегодня у меня такая же проблема, и я решил попробовать новый генератор:
function generateCombinations(array $array) { foreach (array_pop($array) as $value) { if (count($array)) { foreach (generateCombinations($array) as $combination) { yield array_merge([$value], $combination); }; } else { yield [$value]; } } } foreach (generateCombinations(['a' => ['A'], 'b' => ['B'], 'c' => ['C', 'D'], 'd' => ['E', 'F', 'G']]) as $c) { var_dump($c); }
Результат:
array(4) { [0]=> string(1) "E" [1]=> string(1) "C" [2]=> string(1) "B" [3]=> string(1) "A" } array(4) { [0]=> string(1) "E" [1]=> string(1) "D" [2]=> string(1) "B" [3]=> string(1) "A" } array(4) { [0]=> string(1) "F" [1]=> string(1) "C" [2]=> string(1) "B" [3]=> string(1) "A" } array(4) { [0]=> string(1) "F" [1]=> string(1) "D" [2]=> string(1) "B" [3]=> string(1) "A" } array(4) { [0]=> string(1) "G" [1]=> string(1) "C" [2]=> string(1) "B" [3]=> string(1) "A" } array(4) { [0]=> string(1) "G" [1]=> string(1) "D" [2]=> string(1) "B" [3]=> string(1) "A" }