2011-12-19 25 views
26

Tôi đang cố gắng tìm tất cả các kết hợp của các mục trong một số mảng. Số lượng mảng là ngẫu nhiên (có thể là 2, 3, 4, 5 ...). Số phần tử trong mỗi mảng là ngẫu nhiên quá ...Làm thế nào để tạo ra trong PHP tất cả các kết hợp của các mục trong nhiều mảng

Đối dụ, tôi có 3 mảng:

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

Tôi muốn tạo ra một mảng với 3 x 3 x 2 = 18 tổ hợp :

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

Vấn đề là tạo ra một chức năng với một số biến của mảng nguồn ...

+1

Bạn luôn muốn một phần tử từ * mỗi * mảng? – goat

Trả lời

43

đây là giải pháp đệ quy:

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

Tôi nên thay đổi chức năng này như thế nào nếu tôi muốn kết hợp duy nhất cho các mảng được sao chép? Ví dụ, nếu tôi có mảng ('A1', 'A2', 'A3'), mảng ('A1', 'A2', 'A3'), mảng ('C1', 'C2') và tôi muốn kết quả là "A1, A2, C1", "A1, A3, C1", v.v. nhưng KHÔNG "A1, A1, C1"? Ngoài ra (nếu tôi không hỏi quá nhiều;), {"A1", "A2", "C1"} thì giống như {"A2", "A1", "C1"} vì vậy tôi chỉ muốn 1 kết hợp? –

+0

@AlexAngelico - và cho bất kỳ ai khác có cùng câu hỏi, hãy xem array_unique, http://php.net/manual/en/function.array-unique.php –

13

Đây là sản phẩm Descartes, và tôi chỉ asked the same question not too long ago. Đây là số 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

Liên kết tới trang web PHP dường như không dẫn đến bất cứ điều gì về chức năng này . Bạn có thể đưa ra một ví dụ về cách gọi nó? – JohnK

+0

Chức năng này mất hơn 2,5 lần miễn là chức năng của Lolo xử lý cùng một mảng. –

2

Mã này bên cạnh sự đơn giản, nhận tất cả kết hợp nhiều mảng và giữ phím.

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

dụ:

Array 
(
    Array 
    (
     '1' => 'White', 
     '2' => 'Green', 
     '3' => 'Blue' 
    ), 
    Array 
    (
     '4' =>' Small', 
     '5' => 'Big' 
    ) 
) 

Sẽ trả lại:

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

Không biết tại sao một người khác lại bỏ phiếu này. Giải pháp này làm việc hoàn hảo cho tôi và bảo tồn các phím mảng như tôi muốn nó. +1 – Eric

2

Tôi biết câu hỏi này là cũ, nhưng tôi có cùng một vấn đề ngày hôm nay và đã quyết định cung cấp cho các mới Máy phát điện thử:

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

Kết quả:

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

Khi đơn đặt hàng không quan trọng, đó là Kết hợp. Khi thứ tự quan trọng thì đó là một phép hoán vị. Trong trường hợp này, đó là một phép hoán vị chứ không phải là một sự kết hợp. –

Các vấn đề liên quan