2015-09-28 82 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>"; 

?>