我在计算存储在数组中的某些数据的“部分”组合(不是排列)的数量时遇到了一些麻烦。为简单起见,数据看起来像:
$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')
);
但可以有任意数量的数组(最多6个),每个数组可以有2到20个选项。改变这种格式实际上是不可能的,因为它是传统的,并且主要用于下拉电源(例如,想象一下服装店,其中数组1是大小,数组2是颜色,数组3是材料)。
我一直在使用一个简单的递归函数(今天早些时候在这里找到)来计算笛卡尔积:
$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;
}
经过少量后期处理:
$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;
}
产生类似的东西:
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
这很棒,而且正是笛卡尔函数应该做的。但是,我真正需要输出的是:
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
没有排列,只是所有部分组合。
据我所知,这个特定的问题在php中没有被问过(虽然我不知道它是什么叫它搜索它,所以如果它有道歉)。我会问,没有人过早地将这个问题作为副本关闭,除非他们理解我想要实现的目标和链接的页面以解决这个问题(不是这个问题使用字符串或排列或者用其他语言解决)。 / p>
代码:http://phpfiddle.org/main/code/2aw-awb
提前致谢!
答案 0 :(得分:2)
伦敦同胞!这是你在找什么?
http://phpfiddle.org/main/code/wy0-t6f
(请原谅可怕的结构,变量名称和其他不完善之处...这是非常晚的。)
方法:从原始数组中获取子数组的所有可能组合,然后在每个子数组上运行笛卡尔和neaten函数。结果数组应包含所有可能的排列(但仍需要排序)。