首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用PHP关联数组查找笛卡尔乘积

使用PHP关联数组查找笛卡尔乘积
EN

Stack Overflow用户
提问于 2011-06-11 04:35:18
回答 7查看 19K关注 0票数 58

假设我有一个如下所示的数组:

代码语言:javascript
复制
Array
(
    [arm] => Array
        (
            [0] => A
            [1] => B
            [2] => C
        )
    [gender] => Array
        (
            [0] => Female
            [1] => Male
        )
    [location] => Array
        (
            [0] => Vancouver
            [1] => Calgary
        )
)

如何找到笛卡尔乘积,同时保留外部关联数组的键并在内部关联数组中使用它们?算法的结果应该是:

代码语言:javascript
复制
Array
(
    [0] => Array
        (
            [arm] => A
            [gender] => Female
            [location] => Vancouver
        )

    [1] => Array
        (
            [arm] => A
            [gender] => Female
            [location] => Calgary
        )

    [2] => Array
        (
            [arm] => A
            [gender] => Male
            [location] => Vancouver
        )

...etc.

我已经查找了相当多的笛卡尔乘积算法,但我被如何保留关联键的细节所困扰。我目前使用的算法只给出了数字索引:

代码语言:javascript
复制
    $result = array();
    foreach ($map as $a) {
        if (empty($result)) {
            $result = $a;
            continue;
        }
        $res = array();
        foreach ($result as $r) {
            foreach ($a as $v) {
                $res[] = array_merge((array)$r, (array)$v);
            }
        }
        $result = $res;
    }

    print_r($result);

任何帮助都将不胜感激。

EN

回答 7

Stack Overflow用户

发布于 2013-04-12 21:53:38

下面是@Jon的笛卡尔函数的优化版本:

代码语言:javascript
复制
function cartesian($input) {
    $result = array(array());

    foreach ($input as $key => $values) {
        $append = array();

        foreach($result as $product) {
            foreach($values as $item) {
                $product[$key] = $item;
                $append[] = $product;
            }
        }

        $result = $append;
    }

    return $result;
}

阅读更多关于此算法背后的数学知识:http://en.wikipedia.org/wiki/Cartesian_product

查看该算法不同语言的更多示例:https://rosettacode.org/wiki/Cartesian_product_of_two_or_more_lists

票数 55
EN

Stack Overflow用户

发布于 2017-07-05 00:09:09

在PHP 7中,@Serg的答案可以缩短为:

代码语言:javascript
复制
function cartesian(array $input)
{
    $result = [[]];
    foreach ($input as $key => $values) {
        $append = [];
        foreach ($values as $value) {
            foreach ($result as $data) {
                $append[] = $data + [$key => $value];
            }
        }
        $result = $append;
    }

    return $result;
}
票数 10
EN

Stack Overflow用户

发布于 2016-08-27 04:15:49

为什么不使用递归生成器..。内存问题:几乎没有

(而且它很美)

代码语言:javascript
复制
function cartesian($a)
{
    if ($a)
    {
        if($u=array_pop($a))
            foreach(cartesian($a)as$p)
                foreach($u as$v)
                    yield $p+[count($p)=>$v];
    }
    else
        yield[];
}

注意:这不会保留密钥;但这是一个开始。

这应该可以做到(未测试):

代码语言:javascript
复制
function acartesian($a)
{
    if ($a)
    {
        $k=end(array_keys($a));
        if($u=array_pop($a))
            foreach(acartesian($a)as$p)
                foreach($u as$v)
                    yield $p+[$k=>$v];
    }
    else
        yield[];
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6311779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档