2010-03-25 29 views
19

我有這個問題,現在彎曲我的腦海裏了一會兒(頭冷不於事無補!),基本上我有一個PHP數組,看起來像這個例子:PHP二維數組輸出所有組合

$array[0][0] = 'apples'; 
$array[0][1] = 'pears'; 
$array[0][2] = 'oranges'; 

$array[1][0] = 'steve'; 
$array[1][1] = 'bob'; 

我想能夠從該表中與這些每個可能的組合產生,但不重複的任意組合(無論它們的位置),因此例如,這將輸出

Array 0   Array 1 
apples    steve 
apples    bob 
pears    steve 
pears    bob 

但是我會像這種能夠與許多不同的數組作爲possib工作樂。

+0

會有陣列2,陣列3中,數組n?還是隻有兩個數組? –

+0

嗨,對不起,沒有更清晰,可能是陣列2,陣列3到陣列n。謝謝。 – stukerr

+0

你需要的是一個在SQL中簡單交叉連接,但需要在PHP中進行思考的問題 –

回答

20

這就是所謂的「笛卡爾積」,在陣列http://php.net/manual/en/ref.array.php PHP手冊頁顯示了一些實現(在評論)。

,這裏是另一個之一:

function array_cartesian() { 
    $_ = func_get_args(); 
    if(count($_) == 0) 
     return array(array()); 
    $a = array_shift($_); 
    $c = call_user_func_array(__FUNCTION__, $_); 
    $r = array(); 
    foreach($a as $v) 
     foreach($c as $p) 
      $r[] = array_merge(array($v), $p); 
    return $r; 
} 

$cross = array_cartesian(
    array('apples', 'pears', 'oranges'), 
    array('steve', 'bob') 
); 

print_r($cross); 
+0

偉大的東西,正是我所需要的。非常感謝 – stukerr

+0

讓我們把真正的頁面放在那裏:http://php.net/manual/en/ref.array.php :) –

+1

如果這個函數存在於一個類中,你可能想要像這樣改變user_func調用:'' $ c = call_user_func_array(array($ this,__ FUNCTION__),$ _);'。另外,如果輸入數組大小不等,它可以給出警告(不是數組)。 – Nanne

-2

在MySQL數據庫中會是這樣的:

SELECT * 
FROM `options`, `groups` 

這是所有:)

1

這工作,我認爲 - 雖然寫它後我意識到這是非常相似,別人已經把,但它確實給你所要求的格式的數組。對不起,變量命名。

$output = array(); 
combinations($array, $output); 
print_r($output); 

function combinations ($array, & $output, $index = 0, $p = array()) { 
    foreach ($array[$index] as $i => $name) { 
     $copy = $p; 
     $copy[] = $name; 
     $subIndex = $index + 1; 
     if (isset($array[$subIndex])) { 
      combinations ($array, $output, $subIndex, $copy); 
     } else { 
      foreach ($copy as $index => $name) { 
       if (!isset($output[$index])) { 
        $output[$index] = array(); 
       } 
       $output[$index][] = $name; 
      } 
     } 
    } 
} 
1

@ user187291

我改性這是

function array_cartesian() { 
    $_ = func_get_args(); 
    if (count($_) == 0) 
     return array(); 
    $a = array_shift($_); 
    if (count($_) == 0) 
     $c = array(array()); 
    else 
     $c = call_user_func_array(__FUNCTION__, $_); 
    $r = array(); 
    foreach($a as $v) 
     foreach($c as $p) 
      $r[] = array_merge(array($v), $p); 
    return $r; 
} 

所以它返回所有重要的空數組(相同的結果,因爲沒有組合)時,傳遞0的參數。

只注意到這一點,因爲我使用它像

$combos = call_user_func_array('array_cartesian', $array_of_arrays); 
1
foreach($parentArray as $value) { 
    foreach($subArray as $value2) { 
     $comboArray[] = array($value, $value2); 
    } 
} 

不要評判我。

+0

「當然,當sizeof($ array)> = 2時它必須工作。」 –

0
function array_comb($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; 
} 
3

Syom複製http://www.php.net/manual/en/ref.array.php#54979但我適應它這個成爲關聯版本:

function array_cartesian($arrays) { 
    $result = array(); 
    $keys = array_keys($arrays); 
    $reverse_keys = array_reverse($keys); 
    $size = intval(count($arrays) > 0); 
    foreach ($arrays as $array) { 
    $size *= count($array); 
    } 
    for ($i = 0; $i < $size; $i ++) { 
    $result[$i] = array(); 
    foreach ($keys as $j) { 
     $result[$i][$j] = current($arrays[$j]); 
    } 
    foreach ($reverse_keys as $j) { 
     if (next($arrays[$j])) { 
     break; 
     } 
     elseif (isset ($arrays[$j])) { 
     reset($arrays[$j]); 
     } 
    } 
    } 
    return $result; 
} 
2

我需要做同樣的事情,我嘗試了之前發佈的解決方案,但無法使它們工作。我從這個聰明的傢伙http://www.php.net/manual/en/ref.array.php#54979樣本。然而,他的樣本沒有管理的不重複組合的概念。所以我包括那部分。這裏是我的改良版,希望它有助於:

$data = array(
     array('apples', 'pears', 'oranges'), 
     array('steve', 'bob') 
    ); 

    $res_matrix = $this->array_cartesian_product($data); 

    foreach ($res_matrix as $res_array) 
    { 
     foreach ($res_array as $res) 
     { 
      echo $res . " - "; 
     } 
     echo "<br/>"; 
    } 


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); 
    $res_index = 0; 
    for ($i = 0; $i < $size; $i++) 
    { 
     $is_duplicate = false; 
     $curr_values = array(); 
     for ($j = 0; $j < $sizeIn; $j++) 
     { 
      $curr = current($arrays[$j]); 
      if (!in_array($curr, $curr_values)) 
      { 
       array_push($curr_values , $curr); 
      } 
      else 
      { 
       $is_duplicate = true; 
       break; 
      } 
     } 
     if (!$is_duplicate) 
     { 
      $result[ $res_index ] = $curr_values; 
      $res_index++; 
     } 
     for ($j = ($sizeIn -1); $j >= 0; $j--) 
     { 
      $next = next($arrays[ $j ]); 
      if ($next) 
      { 
       break; 
      } 
      elseif (isset ($arrays[ $j ])) 
      { 
       reset($arrays[ $j ]); 
      } 
     } 
    } 
    return $result; 
} 

其結果將是這樣的:
蘋果 - 史蒂夫
蘋果鮑勃 -
梨 - 史蒂夫
梨鮑勃 -
橙子 - 史蒂夫
橘子鮑勃 -

如果該數據陣列是這樣的:

$data = array(
     array('Amazing', 'Wonderful'), 
     array('benefit', 'offer', 'reward'), 
     array('Amazing', 'Wonderful') 
    ); 

然後將打印這樣的:

驚人 - 效益 - 美味
驚人 - 報價 - 美味
驚人 - 獎勵 - 美味
精彩 - 效益 - 驚人
精彩 - 報價 - 令人驚歎的
精彩 - 獎勵 - 驚人

0

我不得不從產品選項進行組合。該解決方案使用遞歸和與2D陣列的工作原理:

function options_combinations($options) { 
    $result = array(); 
    if (count($options) <= 1) { 
     $option = array_shift($options); 
     foreach ($option as $value) { 
      $result[] = array($value); 
     } 
    } else { 
     $option = array_shift($options); 
     $next_option = options_combinations($options); 
     foreach ($next_option as $next_value) { 
      foreach ($option as $value) { 
       $result[] = array_merge($next_value, array($value)); 
      } 
     } 
    } 
    return $result; 
} 

$options = [[1,2],[3,4,5],[6,7,8,9]]; 
$c = options_combinations($options); 
foreach ($c as $combination) { 
    echo implode(' ', $combination)."\n"; 
} 
0

優雅的實現基於天然Python函數itertools.product

function direct_product(array ...$arrays) 
{ 
    $result = [[]]; 
    foreach ($arrays as $array) { 
     $tmp = []; 
     foreach ($result as $x) { 
      foreach ($array as $y) { 
       $tmp[] = array_merge($x, [$y]); 
      } 
     } 
     $result = $tmp; 
    } 
    return $result; 
}