【问题标题】:Combinations of all sub array elements without repeats没有重复的所有子数组元素的组合
【发布时间】:2015-05-19 17:34:09
【问题描述】:

我有来自数据库的“属性”。每个属性都有许多值。现在我想混合这些值来创建独特的组合。

输入示例:

$a = array(
    35=>array('green','red','brown'),
    36=>array('fox','house','dog')
);

输出 - 二维元素的所有可能组合。下面的示例输出:

$output = array(
    array(35=>'green',36=>'fox'),
    array(35=>'green',36=>'house'),
    array(35=>'green',36=>'dog'),
    array(35=>'red',36=>'fox'),
    array(35=>'red',36=>'house'),
    array(35=>'red',36=>'dog'),
    array(35=>'brown',36=>'fox'),
    array(35=>'brown',36=>'house'),
    array(35=>'brown',36=>'dog'),
);

我的函数没有重复:

function myfunction($a){

    $keys = array_keys($a);
    $result = array();

    if(count($keys)==0){
        $result = array();
    }
    elseif(count($keys)==1){
        $k = $keys[0];
        foreach($a[$k] as $v){
            $result[] = array($k=>$v);
        }
    }
    elseif(count($keys)==2){
        $k1 = $keys[0];
        $k2 = $keys[1];
        foreach($a[$k1] as $v1){
            foreach($a[$k2] as $v2){
                $result[] = array($k1=>$v1,$k2=>$v2);
            }
        }
    }
    elseif(count($keys)==3){
        $k1 = $keys[0];
        $k2 = $keys[1];
        $k3 = $keys[2];
        foreach($a[$k1] as $v1){
            foreach($a[$k2] as $v2){
                foreach($a[$k3] as $v3){
                    $result[] = array($k1=>$v1,$k2=>$v2,$k3=>$v3);
                }
            }
        }
    }
    else{
        throw new Exception('To much keys', 1);
    }

    return $result;
}

【问题讨论】:

  • 那么您有一个多维数组$a,其中包含您想要从中创建所有组合的值?组合应该始终包含 2 个值还是每个数组中只有一个值? (例如,如果你有 3 个数组,每个组合应该有 3 个值还是 2 个?)
  • 每个组合中的元素数量等于第一维数组键的数量。每个“子数组”中的一个值(来自第二维的数组)。
  • 您现在在 SO 上有两次这个问题:stackoverflow.com/q/29120826/3933332 我认为您可以删除另一个,因为您首先在 SO 上发布了这个问题

标签: php arrays algorithm recursion combinations


【解决方案1】:

这应该适合你:

那么这段代码有什么作用呢?

1。一共有多少种组合?

所以首先的问题是有多少组合,答案是你必须将每个数组的数量相乘。

所以(c = 数量1):

carray 1 * carray 2 * ... * carray n

具体到你的例子:

c数组 1 * c数组 2= 3 * 3 = 9

*1 如果你想知道为什么我选择 c 作为金额,因为 php 中的函数 count()

2。获取所有组合

我们现在如何得到所有数组长度的所有组合?

非常简单,我们只需遍历所有组合(开始时只是一个空组合 ([] == array())),我们已经拥有下一个数组,直到我们获得所需的长度,在这种情况下是最后一个最后一个数组的迭代。

举个例子:

Array with the elements (Empty array is '[]'):

[
    [1, 2],
    [3, 4]
]

                               //new combinations for the next iteration
                               |
array NAN*:

    Combinations:
                  - []         |  -> []
                                  |
array 1 [1,2]:       -------------
                    |             |
    Combinations:   v             v
                  - []    + 1  |  -> [1]  
                  - []    + 2  |  -> [2]   
                                  |
array 2 [3,4]:       -------------
                    |             |
    Combinations:   v             v
                  - []    + 3  |  -> [3]
                  - []    + 4  |  -> [4]
                  - [1]   + 3  |  -> [1,3]
                  - [1]   + 4  |  -> [1,4]
                  - [2]   + 3  |  -> [2,3]
                  - [2]   + 4  |  -> [2,4]     
                               //^ All combinations here

* NAN:不是数字

正如您在上面的示例中看到的那样,我们现在拥有所有组合以及我们拥有的所有数组数量的长度。

但是为了只获得具有所需长度的组合,我们每次迭代都会覆盖结果数组,这样最后只有具有预期长度的组合才会出现在结果数组中。

代码:

<?php

    $data = [
            35 => ["green", "red", "brown"],
            36 => ["fox", "house", "dog"]
        ];

    $combinations = [[]];
    $comKeys = array_keys($data);


    for ($count = 0; $count < count($comKeys); $count++) {
        $tmp = [];
        foreach ($combinations as $v1) {
            foreach ($data[$comKeys[$count]] as $v2)
                $tmp[] = $v1 + [$comKeys[$count] => $v2];

        }
        $combinations = $tmp;
    }

    print_r($combinations);

?>

输出:

Array
(
    [0] => Array
        (
            [35] => green
            [36] => fox
        )

    [1] => Array
        (
            [35] => green
            [36] => house
        )

    [2] => Array
        (
            [35] => green
            [36] => dog
        )

    [3] => Array
        (
            [35] => red
            [36] => fox
        )

    [4] => Array
        (
            [35] => red
            [36] => house
        )

    [5] => Array
        (
            [35] => red
            [36] => dog
        )

    [6] => Array
        (
            [35] => brown
            [36] => fox
        )

    [7] => Array
        (
            [35] => brown
            [36] => house
        )

    [8] => Array
        (
            [35] => brown
            [36] => dog
        )

)

【讨论】:

  • 这确实是最好的解决方案,不需要递归。请注意,并非所有服务器都具有最新的 PHP,并且不支持新的数组语法。这可能会让一些人感到困惑。
  • 完美运行。现在,我将研究它是如何工作的。非常感谢哥们! :)
【解决方案2】:

你可以使用这个:https://gist.github.com/jwage/11193216

使用下面的代码:

<?php
$attributes = [
    [
        'P', 'M', 'G', 'XG'
    ],
    [
        'Vermelho', 'Amarelo', 'Verde'
    ],
];



function array_mix($leftItems, $rightItems)
{
    $results   = [];
    foreach ($leftItems as $leftItem) {
        foreach ($rightItems as $key => $rightItem) {
            $results[] = array_merge((array) $leftItem, (array) $rightItem);
        }
    }
    return $results;
}

$y = $attributes[0];

foreach($attributes as $key => $attrs) {
    if(isset($attributes[$key + 1]) && is_array($attributes[$key + 1])) {
        $y = array_mix($y, $attributes[$key + 1]);
    }
}

var_dump($y);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 2022-01-25
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多