一尘不染

所有子数组元素的组合,无重复

algorithm

我有数据库的“属性”。每个属性都有许多值。现在,我想混合这些值以创建唯一的组合。

输入示例:

$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;
}

阅读 231

收藏
2020-07-28

共1个答案

一尘不染

这应该为您工作:

那么这段代码是做什么的呢?

1.有多少种组合?

因此,首先要问的是有多少种组合,答案是必须将每个数组的数量彼此相乘。

因此(c =数量1):

c 数组1 * c 数组2 * … * c 数组n

并针对您的示例:

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

  • 1而且,如果您想知道为什么我要选择c金额,因为count()php 中的功能

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
        )

)
2020-07-28