PHP:在多维数组中枚举所有可能的组合

时间:2014-04-29 16:37:06

标签: php arrays multidimensional-array

我有一个数组:

$array = array ( 'tag1' => array ('apple', 'orange','cherries') ,
                  'tag2' => array ('delicious' , 'yummy', 'tasty', 'good')
                  'tag3' => array ('green', 'red', 'orange')
                );

我想生成另一个包含所有可能组合的数组,无论顺序如何,但包括每个组合(power set)。例如:

$result = array (
             array(),
             array('tag1' => 'apple'),
             array('tag1' => 'orange'),
             array('tag1' => 'cherries'),
             array('tag2' => 'delicious'),
             array('tag2' => 'yummy'),
             array('tag2' => 'tasty'),
             array('tag2' => 'good'),
             array('tag3' => 'green'),
             array('tag3' => 'red'),
             array('tag3' => 'orange'),
             array('tag1' => 'apple', 'tag2' => 'delicious'),
             array('tag1' => 'apple', 'tag2' => 'yummy'),
             array('tag1' => 'apple', 'tag2' => 'tasty'),
             array('tag1' => 'apple', 'tag2' => 'good'),
             array('tag1' => 'apple', 'tag3' => 'green'),
             array('tag1' => 'apple', 'tag3' => 'red'),
             array('tag1' => 'apple', 'tag3' => 'orange'),
             array('tag1' => 'apple', 'tag2' => 'delicious', 'tag3' => 'green'),
             array('tag1' => 'apple', 'tag2' => 'delicious', 'tag3' => 'red'),
             array('tag1' => 'apple', 'tag2' => 'delicious', 'tag3' => 'orange'),
             ..
);

有谁知道可以写什么功能来实现这个目标?我相信它可能必须是一个递归函数,但到目前为止我还没有能够提出任何符合我所有要求的东西。

3 个答案:

答案 0 :(得分:2)

function power_set($array) {
    $results = [[]];

    foreach($array as $tag => $features) {
        foreach ($results as $combination) {
            foreach ($features as $feature) {
                array_push($results, array_merge([$tag => $feature], $combination));
            }
        }
    }

    return $results;
}

$array = array(
    'tag1' => array ('apple', 'orange','cherries') ,
    'tag2' => array ('delicious' , 'yummy', 'tasty', 'good'),
    'tag3' => array ('green', 'red', 'orange')
);

print_r(power_set($array))

答案 1 :(得分:1)

正如您所说,您可以使用递归,如下所示:

$array = array ( 'tag1' => array ('apple', 'orange','cherries') ,
                  'tag2' => array ('delicious' , 'yummy', 'tasty', 'good'),
                  'tag3' => array ('green', 'red', 'orange')
                );

function expand($sofar, $rest, &$result) {

    if (empty($rest))
        return;

    // get tag name and possible values
    reset($rest);
    $tag = key($rest);
    $values = array_shift($rest);

    // loop through tag's values
    foreach ($values as $value) {

        // prepare new result using $sofar with new tag value added
        $subresult = $sofar;
        $subresult[$tag] = $value;
        $result[] = $subresult;

        // continue expansion of next tag
        expand($subresult, $rest, $result);
    }
}

$result = array();
expand(array(), $array, $result);

print_r($result);

答案 2 :(得分:1)

我写了一个非递归函数... :)

function powerset($array)
{
    $results = array(array());
    foreach($array as $key => $values)
    {
        $new_results = array();
        foreach($results as $old_dict)
        {
            foreach($values as $val)
            {
                $new_dict = $old_dict;
                $new_dict[$key] = $val;
                $new_results[] = $new_dict;
            }
        }
        $results = array_merge($results, $new_results);
    }
    return $results;
}