2011-12-19 68 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