从多个嵌套数组中获取所有组合

Posted

技术标签:

【中文标题】从多个嵌套数组中获取所有组合【英文标题】:Get all combinations from multiple nested arrays 【发布时间】:2012-03-05 10:09:53 【问题描述】:

我正在尝试在 php 中提出一种算法来获取嵌套数组的所有组合:

Array
(
    [0] => Array
        (
            [0] => Option Object
                (
                    [strValue] => rough
                )

            [1] => Option Object
                (
                    [strValue] => smooth
                )

            [2] => Option Object
                (
                    [strValue] => coarse
                )

        )

    [1] => Array
        (
            [0] => Option Object
                (
                    [strValue] => shiney
                )

            [1] => Option Object
                (
                    [strValue] => mat
                )

        )

    [2] => Array
        (
            [0] => Option Object
                (
                    [strValue] => Large
                )

            [1] => Option Object
                (
                    [strValue] => Medium
                )

            [2] => Option Object
                (
                    [strValue] => Small
                )

            [3] => Option Object
                (
                    [strValue] => very large
                )

        )

)

所以我会得到类似的东西:

-粗糙,闪亮,大

-粗糙,闪亮,小

-粗糙,闪亮,中等

-粗糙,闪亮,非常大

-光滑,闪亮,大

-光滑,闪亮,小

-光滑,闪亮,中等

-光滑,闪亮,非常大

等(在本例中应为 24)

我已经尝试了各种 foreach 示例和一些基本的递归函数,但我似乎没有得到什么快。如果有人能给出如何解决这个问题的基本大纲,我将非常感激,谢谢!

【问题讨论】:

您的代码(理想情况下会添加到问题中)究竟是如何失败的?因为乍一看,一组 3 个嵌套的 for 循环应该是解决您的问题所需要的全部。 我不会说数组是嵌套的,必然。它们都包含在父数组中,但它们彼此之间没有嵌套。但是要使用它们创建一个cartesian product,你确实需要嵌套循环。 Finding cartesian product with PHP associative arrays的可能重复 好吧,它不一定只需要 3 个 foreach。上面可以有任意数量的额外元素 刚刚有机会试用你提到的笛卡尔函数,非常感谢! 【参考方案1】:

我刚刚写了这个,它适用于任何长度的数组..

<?php

function cartesian_product($a) 
  $result = array(array());
  foreach ($a as $list) 
    $_tmp = array();
    foreach ($result as $result_item) 
      foreach ($list as $list_item) 
        $_tmp[] = array_merge($result_item, array($list_item));
      
    
    $result = $_tmp;
  
  return $result;



// Let's test this..                                                                                                                                                                                    

header('Content-type: text/plain');

$a = array(
  array('rough','smooth','coarse'),
  array('shiney','mat'),
  array('small','medium','large','x-large'),
);

$result = cartesian_product($a);
foreach ($result as $row) 
  print implode(", ", $row) ."\n";

编辑:稍微改进了代码..

【讨论】:

哦,仅供参考,在 Python 中你会这样做:***.com/questions/533905/… :)【参考方案2】:

是时候嵌套一些 foreach 循环了!

<?php
$array1 = array('rough', 'smooth', 'coarse');
$array2 = array('shiny', 'matte');
$array3 = array('very large', 'large', 'medium', 'small');

foreach($array1 as $i)
    foreach($array2 as $j)
        foreach($array3 as $k)
            $output[] = "$i, $j, $k";

var_dump($output);
/* ouput
array
  0 => string 'rough, shiny, very large' (length=24)
  1 => string 'rough, shiny, large' (length=19)
  2 => string 'rough, shiny, medium' (length=20)
  3 => string 'rough, shiny, small' (length=19)
  4 => string 'rough, matte, very large' (length=24)
  5 => string 'rough, matte, large' (length=19)
  6 => string 'rough, matte, medium' (length=20)
  7 => string 'rough, matte, small' (length=19)
  8 => string 'smooth, shiny, very large' (length=25)
  9 => string 'smooth, shiny, large' (length=20)
  10 => string 'smooth, shiny, medium' (length=21)
  11 => string 'smooth, shiny, small' (length=20)
  12 => string 'smooth, matte, very large' (length=25)
  13 => string 'smooth, matte, large' (length=20)
  14 => string 'smooth, matte, medium' (length=21)
  15 => string 'smooth, matte, small' (length=20)
  16 => string 'coarse, shiny, very large' (length=25)
  17 => string 'coarse, shiny, large' (length=20)
  18 => string 'coarse, shiny, medium' (length=21)
  19 => string 'coarse, shiny, small' (length=20)
  20 => string 'coarse, matte, very large' (length=25)
  21 => string 'coarse, matte, large' (length=20)
  22 => string 'coarse, matte, medium' (length=21)
  23 => string 'coarse, matte, small' (length=20)
*/
?>

【讨论】:

感谢您提供使回复易于验证的输出【参考方案3】:

这是psuedo-PHP中的蛮力(最差效率)算法:

$array1 = $array[0];
$array2 = $array[1];
$array3 = $array[2];

$results = array();
for( $i = 0; $i < count( $array1); $i++)
    for( $j = 0; $j < count( $array2); $j++)
        for( $k = 0; $k < count( $array3); $k++)
            $results[] = $array1[$i] . ',' . $array2[$j] . ',' . $array3[$k];

【讨论】:

正如我刚才在上面评论的,它不一定只需要 3 个 foreach。上面可以有任意数量的额外元素,这是动态的,所以我不能只将它限制为 3 嵌套 for/foreach 哦,我的错。您的标题具有误导性,因为它专门说 3 个数组。

以上是关于从多个嵌套数组中获取所有组合的主要内容,如果未能解决你的问题,请参考以下文章

从数组(Java)中获取所有大小 n 组合的算法? [关闭]

从flutter中的多个嵌套json数组中获取值

如何从具有嵌套对象数组的对象数组中获取所有特定值?

JavaScript,从几个数组中获取所有唯一组合[重复]

从嵌套属性数组中获取对象嵌套值

如何从嵌套的对象数组中获取每个父级的值