查找数组键与值的组合

时间:2016-12-01 16:48:30

标签: php arrays math combinations

为了优化输出,我最近遇到了一种情况,我必须在数组中获取数组键的所有组合。我查看了几个地方(包括StackOverflow),但找不到解决方案,因为大多数都与排列有关而不是组合。

鉴于此输入

$input = ['jack' => 11, 'moe' => 12, 'shane' => 12];

输出应该是这样的(数组中的顺序无关紧要)。

$output = [     
   ['jack'  => 11],
   ['jack'  => 11, 'moe' => 12]
   ['jack'  => 11, 'moe' => 12, 'shane' => 12]
   ['moe'   => 12],
   ['moe'   => 12, 'shane' => 12]
   ['shane' => 12],
   ['shane' => 12, 'jack' => 11]
];

我尝试了这个但是在第三次迭代之后它不起作用。

function combination(array $inputs, array $temp, &$collect) {

    if (!empty($temp)) {

        $collect[] = $temp;
    }

    for ($i = 0; $i < sizeof($inputs); $i++) {

        $inputCopy = $inputs;

        $elem = array_splice($inputCopy, $i, 1); 

        if (count($inputCopy) > 0) {

            $temp[array_keys($elem)[0]] = array_values($elem)[0];

            combination($inputCopy, $temp, $collect);

        } else {

            $temp[array_keys($elem)[0]] = array_values($elem)[0];
            $collect[] = $temp;
            $temp = [];
        }

        $i++;

    }
}

虽然我需要PHP甚至Python(不使用itertools组合),但Java,Javascript对我有用。

3 个答案:

答案 0 :(得分:2)

我找到了一种做你想做的事的方法,但绝对是,这不是一个“花哨的”#34;解。我建议你稍微用它来找到更好的东西,但至少这会给你带来结果。

你走了:

   <?php

    $baseArray = [
    "joe"   => 11,
    "molly" => 12,
    "sam"   => 13,
    ];

function getAllPermutations($array = []) {
    if (empty($array)) {
        return [];
    }

    $result = [];

    foreach ($array as $key => $value) {
        unset($array[$key]);
        $subPermutations = getAllPermutations($array);
        $result[] = [$key => $value];
        foreach ($subPermutations as $sub) {
            $result[] = array_merge([$key => $value] , $sub);
        }
    }
    return $result;
}

print_r(getAllPermutations($baseArray));

输出为:

Array
(
    [0] => Array
        (
            [joe] => 11
        )

    [1] => Array
        (
            [joe] => 11
            [molly] => 12
        )

    [2] => Array
        (
            [joe] => 11
            [molly] => 12
            [sam] => 13
        )

    [3] => Array
        (
            [joe] => 11
            [sam] => 13
        )

    [4] => Array
        (
            [molly] => 12
        )

    [5] => Array
        (
            [molly] => 12
            [sam] => 13
        )

    [6] => Array
        (
            [sam] => 13
        )

)    }

希望这会有所帮助。

答案 1 :(得分:1)

你在这里读到了非常聪明的非递归算法:PHP: Find every combination of an Array。您可以采用它(主要是复制和粘贴)来编写generator function

function keyCombinations($array)
{
    $keys = array_keys($array);

    $num = count($keys); 
    $total = pow(2, $num);

    for ($i = 1; $i < $total; $i++) {
        $combination = [];
        for ($j = 0; $j < $num; $j++) {
            if (pow(2, $j) & $i) {
                $key = $keys[$j];

                $combination[$key] = $array[$key];
            }
        } 
        yield $combination;
    }
}

这里有一点重要。在使用$i初始化的原始文章0中,我们使用1对其进行初始化,以从结果中排除空数组。

拥有此功能,您可以获得所有组合:

foreach (keyCombinations($input) as $combination) {
    print_r($combination);
}

这是working demo

答案 2 :(得分:0)

如果在最终组合中包含空集,则问题等同于枚举二进制数&#34; n&#34;位。在哪里&#34; n&#34;是集合中元素的数量。

你需要像这样的递归算法:

def comb(initialSet, results=[], currentIndex=0, currentResult=[]):
    if currentIndex >= len(initialSet):
        results.append( currentResult[:] )
    else:
        currentResult.append( initialSet[currentIndex] )
        comb(initialSet, results, currentIndex + 1, currentResult)
        currentResult.pop()
        comb(initialSet, results, currentIndex + 1, currentResult)
    return results