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


PHP: Enumerate All Possible Combinations in Multi-dimensional Array

我有一个数组:

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

我想用每一个可能的组合生成另一个数组,不管顺序如何,但包括每一个组合(幂集(。例如:

$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'),
             ..
);

有人知道可以写什么函数来实现这一点吗?我相信它可能是一个递归函数,但到目前为止,我还没能想出任何适合我所有需求的函数。

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))

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

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

我写了一个非递归函数…:(

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