简体   繁体   English

来自多个数组的部分组合

[英]Partial combinations from several arrays

I'm having a little trouble calculating the number of "partial" combinations (not permutations) of some data stored in arrays.我在计算存储在数组中的某些数据的“部分”组合(不是排列)的数量时遇到了一些麻烦。 For simplicity's sake the data looks something like:为简单起见,数据类似于:

$test = array(
        array('1:1' => 'Option 1:1', '1:2' => 'Option 1:2', '1:3' => 'Option 1:3'),
        array('2:1' => 'Option 2:1', '2:2' => 'Option 2:2', '2:3' => 'Option 2:3'),
        array('3:1' => 'Option 3:1', '3:2' => 'Option 3:2', '3:3' => 'Option 3:3')
    );

but can have any number of arrays (up to 6) and each one can have between 2 and 20 options.但可以有任意数量的数组(最多 6 个),每个数组可以有 2 到 20 个选项。 Changing this format isn't really possible because it's legacy and is essentially used to power dropdowns (eg imagine a clothing store where array 1 is size, array 2 is colour and array 3 is material).改变这种格式实际上是不可能的,因为它是遗留的,并且主要用于为下拉菜单提供动力(例如想象一个服装店,其中数组 1 是大小,数组 2 是颜色,数组 3 是材料)。

I have been using a simple recursive function (found on here earlier today) to calculate the Cartesian product:我一直在使用一个简单的递归函数(今天早些时候在这里找到)来计算笛卡尔积:

$result = call_user_func_array('cartesian', $test);

function cartesian()
{
    $arrays = func_get_args();

    if(count($arrays) == 0)
    {
        return array(array());
    }

    $array      = array_shift($arrays);
    $recurse    = call_user_func_array(__FUNCTION__, $arrays);
    $return     = array();

    foreach($array as $key => $value)
    {
        foreach($recurse as $result)
        {
            $return[] = array_merge(array($key => $value), $result);
        }
    }

    return $return;
}

Which after a small amount of post processing:其中经过少量后期处理:

$result = neaten($result);

function neaten($array_cartesian)
{   
    $names = array();

    foreach($array_cartesian as $array)
    {
        ksort($array);
        $config_string  = array();
        $name_string    = array();

        foreach($array as $config => $name)
        {
            $config_string[]    = $config;
            $name_string[]      = $name;
        }

        $names[implode(',', $config_string)] = implode(', ', $name_string);
    }

    return $names;
}

Produces something like:产生类似的东西:

Array
(
    [1:1,2:1,3:1] => Option 1:1, Option 2:1, Option 3:1
    [1:1,2:1,3:2] => Option 1:1, Option 2:1, Option 3:2
    [1:1,2:1,3:3] => Option 1:1, Option 2:1, Option 3:3
    [1:1,2:2,3:1] => Option 1:1, Option 2:2, Option 3:1
    [1:1,2:2,3:2] => Option 1:1, Option 2:2, Option 3:2
    [1:1,2:2,3:3] => Option 1:1, Option 2:2, Option 3:3
    [1:1,2:3,3:1] => Option 1:1, Option 2:3, Option 3:1
    [1:1,2:3,3:2] => Option 1:1, Option 2:3, Option 3:2
    [1:1,2:3,3:3] => Option 1:1, Option 2:3, Option 3:3
    [1:2,2:1,3:1] => Option 1:2, Option 2:1, Option 3:1
    [1:2,2:1,3:2] => Option 1:2, Option 2:1, Option 3:2
    [1:2,2:1,3:3] => Option 1:2, Option 2:1, Option 3:3
    [1:2,2:2,3:1] => Option 1:2, Option 2:2, Option 3:1
    [1:2,2:2,3:2] => Option 1:2, Option 2:2, Option 3:2
    [1:2,2:2,3:3] => Option 1:2, Option 2:2, Option 3:3
    [1:2,2:3,3:1] => Option 1:2, Option 2:3, Option 3:1
    [1:2,2:3,3:2] => Option 1:2, Option 2:3, Option 3:2
    [1:2,2:3,3:3] => Option 1:2, Option 2:3, Option 3:3
    [1:3,2:1,3:1] => Option 1:3, Option 2:1, Option 3:1
    [1:3,2:1,3:2] => Option 1:3, Option 2:1, Option 3:2
    [1:3,2:1,3:3] => Option 1:3, Option 2:1, Option 3:3
    [1:3,2:2,3:1] => Option 1:3, Option 2:2, Option 3:1
    [1:3,2:2,3:2] => Option 1:3, Option 2:2, Option 3:2
    [1:3,2:2,3:3] => Option 1:3, Option 2:2, Option 3:3
    [1:3,2:3,3:1] => Option 1:3, Option 2:3, Option 3:1
    [1:3,2:3,3:2] => Option 1:3, Option 2:3, Option 3:2
    [1:3,2:3,3:3] => Option 1:3, Option 2:3, Option 3:3
)

27 total

Which is great, and exactly what a Cartesian function should do.这很好,这正是笛卡尔函数应该做的。 However, what I really need output is something like:但是,我真正需要的输出是这样的:

Array
(
    [1:1]       => Option 1:1
    [1:2]       => Option 1:2
    [1:3]       => Option 1:3
    [2:1]       => Option 2:1
    [2:2]       => Option 2:2
    [2:3]       => Option 2:3
    [3:1]       => Option 3:1
    [3:2]       => Option 3:2
    [3:3]       => Option 3:3
    [1:1,2:1]   => Option 1:1, Option 2:1
    [1:1,2:2]   => Option 1:1, Option 2:2
    [1:1,2:3]   => Option 1:1, Option 2:3
    [1:2,2:1]   => Option 1:2, Option 2:1
    [1:2,2:2]   => Option 1:2, Option 2:2
    [1:2,2:3]   => Option 1:2, Option 2:3
    [1:3,2:1]   => Option 1:3, Option 2:1
    [1:3,2:2]   => Option 1:3, Option 2:2
    [1:3,2:3]   => Option 1:3, Option 2:3
    [1:1,3:1]   => Option 1:1, Option 3:1
    [1:1,3:2]   => Option 1:1, Option 3:2
    [1:1,3:3]   => Option 1:1, Option 3:3
    [1:2,3:1]   => Option 1:2, Option 3:1
    [1:2,3:2]   => Option 1:2, Option 3:2
    [1:2,3:3]   => Option 1:2, Option 3:3
    [1:3,3:1]   => Option 1:3, Option 3:1
    [1:3,3:2]   => Option 1:3, Option 3:2
    [1:3,3:3]   => Option 1:3, Option 3:3
    [2:1,3:1]   => Option 2:1, Option 3:1
    [2:1,3:2]   => Option 2:1, Option 3:2
    [2:1,3:3]   => Option 2:1, Option 3:3
    [2:2,3:1]   => Option 2:2, Option 3:1
    [2:2,3:2]   => Option 2:2, Option 3:2
    [2:2,3:3]   => Option 2:2, Option 3:3
    [2:3,3:1]   => Option 2:3, Option 3:1
    [2:3,3:2]   => Option 2:3, Option 3:2
    [2:3,3:3]   => Option 2:3, Option 3:3
    [1:1,2:1,3:1]   => Option 1:1, Option 2:1, Option 3:1
    [1:1,2:1,3:2]   => Option 1:1, Option 2:1, Option 3:2
    [1:1,2:1,3:3]   => Option 1:1, Option 2:1, Option 3:3
    [1:1,2:2,3:1]   => Option 1:1, Option 2:2, Option 3:1
    [1:1,2:2,3:2]   => Option 1:1, Option 2:2, Option 3:2
    [1:1,2:2,3:3]   => Option 1:1, Option 2:2, Option 3:3
    [1:1,2:3,3:1]   => Option 1:1, Option 2:3, Option 3:1
    [1:1,2:3,3:2]   => Option 1:1, Option 2:3, Option 3:2
    [1:1,2:3,3:3]   => Option 1:1, Option 2:3, Option 3:3
    [1:2,2:1,3:1]   => Option 1:2, Option 2:1, Option 3:1
    [1:2,2:1,3:2]   => Option 1:2, Option 2:1, Option 3:2
    [1:2,2:1,3:3]   => Option 1:2, Option 2:1, Option 3:3
    [1:2,2:2,3:1]   => Option 1:2, Option 2:2, Option 3:1
    [1:2,2:2,3:2]   => Option 1:2, Option 2:2, Option 3:2
    [1:2,2:2,3:3]   => Option 1:2, Option 2:2, Option 3:3
    [1:2,2:3,3:1]   => Option 1:2, Option 2:3, Option 3:1
    [1:2,2:3,3:2]   => Option 1:2, Option 2:3, Option 3:2
    [1:2,2:3,3:3]   => Option 1:2, Option 2:3, Option 3:3
    [1:3,2:1,3:1]   => Option 1:3, Option 2:1, Option 3:1
    [1:3,2:1,3:2]   => Option 1:3, Option 2:1, Option 3:2
    [1:3,2:1,3:3]   => Option 1:3, Option 2:1, Option 3:3
    [1:3,2:2,3:1]   => Option 1:3, Option 2:2, Option 3:1
    [1:3,2:2,3:2]   => Option 1:3, Option 2:2, Option 3:2
    [1:3,2:2,3:3]   => Option 1:3, Option 2:2, Option 3:3
    [1:3,2:3,3:1]   => Option 1:3, Option 2:3, Option 3:1
    [1:3,2:3,3:2]   => Option 1:3, Option 2:3, Option 3:2
    [1:3,2:3,3:3]   => Option 1:3, Option 2:3, Option 3:3
)

63 total

With no permutations, just all partial combinations.没有排列,只有部分组合。

As far as I can tell this specific question hasn't been asked on here in php (though I have no idea what it is called to search for it, so apologies if it has).据我所知,这里没有在 php 中提出这个特定问题(虽然我不知道搜索它的名字是什么,所以如果有的话,我很抱歉)。 I would ask that no-one closes this question prematurely as a duplicate unless they understand what I am trying to achieve and the page linked to solves this EXACT problem (not this problem using strings or permutations or solved in another language for example).我会要求没有人过早地将这个问题作为重复关闭,除非他们理解我想要实现的目标并且链接到的页面解决了这个确切的问题(不是这个问题使用字符串或排列或用另一种语言解决)。

The code: http://phpfiddle.org/main/code/2aw-awb代码: http : //phpfiddle.org/main/code/2aw-awb

Thanks in advance!提前致谢!

A fellow Londoner!一个伦敦人! Is this what you're looking for?这是你要找的吗?

http://phpfiddle.org/main/code/wy0-t6f http://phpfiddle.org/main/code/wy0-t6f

(Please excuse horrible structure, variable names, and other imperfections... it's extremely late.) (请原谅可怕的结构、变量名和其他不完善的地方……太晚了。)

Method: get all possible combinations of sub-arrays from your original array, then run the cartesian and neaten functions on each of them.方法:从原始数组中获取子数组的所有可能组合,然后在每个子数组上运行笛卡尔和对齐函数。 The resulting array should contain all possible permutations (but still needs to be sorted).结果数组应包含所有可能的排列(但仍需要排序)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM