2015-09-28 70 views
0

我有格式的數組:遞歸 - 所有的可能性 - PHP

$array['something_1'] = array('aother_1','aother_2',...,'aother_n') 
$array['something_2'] = array('bother_1','bother_2',...,'bother_n') 
... 
$array['something_m'] = array('zother_1','zother_2',...,'zother_n') 

n,m是可變

我需要做的是創建新表與所有與所有套東西(x)其他的可能性...

$array[] = array('something_1' => 'aother_1','something_2' => 'bother_1', ..., 'something_m' => 'zother_1'); 
$array[] = array('something_1' => 'aother_2','something_2' => 'bother_1', ..., 'something_m' => 'zother_1'); 
... 
$array[] = array('something_1' => 'aother_n','something_2' => 'bother_n', ..., 'something_m' => 'zother_n'); 

基本上想要具有所有可能值的索引集合。

一些真實的例子:

$input = array(
    'obj1' => array('val1','val2','val3'), 
    'obj2' => array('val4','val5') 
); 

$output = array(
    [] => array('obj1' => 'val1','obj2' => 'val4'), 
    [] => array('obj1' => 'val2','obj2' => 'val4'), 
    [] => array('obj1' => 'val3','obj2' => 'val4'), 
    [] => array('obj1' => 'val1','obj2' => 'val5'), 
    [] => array('obj1' => 'val2','obj2' => 'val5'), 
    [] => array('obj1' => 'val3','obj2' => 'val5'), 
) 

真實情況要比這個例子大得多......可能包含像每對象1000分的對象和像20個值。

通常在該例子中,我可以使用雙倍的foreach ...但與1000個對象,使用1000的foreach似乎有點...白癡:d

+1

這個問題上的信息有點短。你可以分享你的嘗試,以及你遇到了什麼問題? –

+0

遞歸有什麼問題?這可能有助於:http://stackoverflow.com/questions/14006609/php-recursion-print-all-elements-of-a-multidimensional-array-with-keys – Pogrindis

+0

我在遞歸思維中很不好...它是真的很難接受任何嘗試......遞歸會被忽略,因爲我們不知道有多少元素......要麼既不索引也不索引值。 –

回答

1

這裏是一個解決方案,佔據N的任意組合和m,並且不使用遞歸邏輯(你不喜歡)。

它有效地跟蹤每個子陣列中的元素數量,將它們降低一個,如果它們達到-1,則設置回原來的數量。

它還使用了一些鏈接列表樣的行爲(終止時,第一個關鍵「curindex」不能降低。)

<?php 
$input = array(
    'obj1' => array('val1','val2','val3'), 
    'obj2' => array('val4','val5'), 
    'obj3' => array('val6','val7') 
); 

// find last key 
$keys = array_keys($input); 
$lastKey = $keys[count($keys)-1]; 

// create currentindex and maxindex for each 
$CMI = array(); 

$former = ''; 
foreach ($input as $key => $valARR){ 
    $CMI[$key]["maxindex"] = count($valARR)-1; 
    $CMI[$key]["curindex"] = count($valARR)-1; 
    // linkedlist like behaviour. obj3 -> obj2 -> obj1 -> '' 
    $CMI[$key]["former"] = $former; 
    $former = $key;  
} 

$output = array(); 
$bRunning = true; 

while ($bRunning){ 
    $oneCombi = array(); 
    foreach ($input as $key => $valARR){ 
     $oneCombi[$key] = $valARR[$CMI[$key]["curindex"]]; 
    } 
    $output[] = $oneCombi; 

    // Now lower curindex of last one, all the way up to first one, then quit. 
    $bLowering = true; 
    $curKey = $lastKey; 
    while ($bLowering){ 
     $CMI[$curKey]["curindex"]--; 
     if ($CMI[$curKey]["curindex"] == -1){ 
      $CMI[$curKey]["curindex"] = $CMI[$curKey]["maxindex"]; 
      $curKey = $CMI[$curKey]["former"]; 
      if ($curKey == ''){ 
       // no more combinations 
       $bLowering = false; 
       $bRunning = false; 
      } 
     } else { 
      $bLowering = false; 
     } 
    } 
} 

// optionally reverse to match your original example: 
$output = array_reverse($output); 

echo "endresult:<pre>"; 
var_dump($output); 
echo "</pre>"; 

?>