2011-12-19 65 views
26

我试图找到几个数组中的项目的所有组合。 数组的数量是随机的(这可以是2,3,4,5 ...)。 元件的每个阵列中的数是随机的太...如何在PHP中生成多个数组中的项目的所有组合

对于为例,我有3个数组:

$arrayA = array('A1','A2','A3'); 
$arrayB = array('B1','B2','B3'); 
$arrayC = array('C1','C2'); 

我想生成用3×3×2 = 18个的组合的阵列:

  • A1,B1,C1
  • A1,B1,C2
  • A1,B2,C1
  • A1, B2,C2
  • A1,B3,C1
  • A1,B3,C2
  • A2,B1,C1
  • A2,B1,C2 ...

问题是创建与源阵列的可变数量的函数...

+1

你总是想从* *每一个数组元素? – goat 2011-12-19 20:30:06

回答

43

这里是递归的溶液:

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') 
     ) 
    ) 
); 
+0

如果我想要重复数组的唯一组合,我应该如何更改此函数?例如,如果我有数组('A1','A2','A3'),数组('A1','A2','A3'),数组('C1','C2'),我想要结果“A1,A2,C1”,“A1,A3,C1”等,但没有“A1,A1,C1”?另外(如果我不要求太多),{“A1”,“A2”,“C1”}与{“A2”,“A1”,“C1”}是一样的,所以我只需要1个组合? – 2013-05-30 01:23:36

+0

@AlexAngelico - 和别人有同样的问题,请参见array_unique,http://php.net/manual/en/function.array-unique.php – 2017-04-04 03:25:00

13

这是一个笛卡尔产品,我只是asked the same question not too long ago。这里是algorithm that is posted on the PHP website

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; 
} 
+0

到PHP网站的链接显然并未导致任何关于此功能。你能举一个例子来援引它吗? – JohnK 2014-07-09 00:28:17

+0

该函数的处理时间超过Lolo函数的2.5倍,以处理相同的数组。 – 2014-09-11 16:26:51

2

这段代码除了简单之外,还可以获得多个数组的所有组合并保留键。

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; 
} 

例:

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 
    ) 
) 
+0

不知道为什么别人低估了这一点。这个解决方案对我来说非常合适,并且像我想要的那样保留了数组键。 +1 – Eric 2016-08-16 18:46:36

2

我知道这个问题是旧的,但我得到了同样的问题,今天决定给新发电机一试:

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" 
} 
+0

当订单无所谓时,它是一个组合。 当订单确实重要时,它是一个置换。 在这种情况下,它是一个排列而不是一个组合。 – 2016-12-20 21:01:53