假设我有一个如下所示的数组:
Array
(
[arm] => Array
(
[0] => A
[1] => B
[2] => C
)
[gender] => Array
(
[0] => Female
[1] => Male
)
[location] => Array
(
[0] => Vancouver
[1] => Calgary
)
)
如何找到笛卡尔乘积,同时保留外部关联数组的键并在内部关联数组中使用它们?算法的结果应该是:
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.
我已经查找了相当多的笛卡尔乘积算法,但我被如何保留关联键的细节所困扰。我目前使用的算法只给出了数字索引:
$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);
任何帮助都将不胜感激。
发布于 2013-04-12 21:53:38
下面是@Jon的笛卡尔函数的优化版本:
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
发布于 2017-07-05 00:09:09
在PHP 7中,@Serg的答案可以缩短为:
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;
}
发布于 2016-08-27 04:15:49
为什么不使用递归生成器..。内存问题:几乎没有
(而且它很美)
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[];
}
注意:这不会保留密钥;但这是一个开始。
这应该可以做到(未测试):
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[];
}
https://stackoverflow.com/questions/6311779
复制相似问题