如何获得多个多维数组的所有可能交集?
Posted
技术标签:
【中文标题】如何获得多个多维数组的所有可能交集?【英文标题】:How to get all possible intersections of multiple multidimensional arrays? 【发布时间】:2015-12-12 12:27:18 【问题描述】:我在 php 中有两个这样的数组:
$array1 = array(array("1", "3", "4"), array("1", "4"));
$array2 = array(array("5", "4", "3", "2"), array("5", "3"));
现在我想得到这两个多维数组的所有可能的交集。意味着我总共会得到 4 个数组:
$array1[0]
& $array2[0]
$array1[1]
& $array2[0]
$array1[0]
& $array2[1]
$array1[1]
& $array2[1]
我可以使用array_intersect()
从一维数组中获取交集。但是我怎样才能得到多个多维数组的所有可能的交集呢?
【问题讨论】:
【参考方案1】:这里我们创建了一个包含所有数组组合的数组,因此我们以后可以取这些数组的交集。
数组组合
首先我们需要创建所有可能的数组组合。即:
carray 1 * carray 2 * ... * carray n
"c" 只表示数组的count()
因此,在您的具体示例中,它将是:
c数组 1 * c数组 2 => 2 * 2 => 4 个组合
现在我们需要获取所有这些组合并将它们放入一个数组中。为此,我们从一个空的 $combinations
数组开始。然后我们循环遍历数组中的所有组合并将下一个数组合并到其中,直到我们获得所需的组合长度,在本例中为我们拥有的数组数量。
举个例子:
Array with the elements (Empty array is '[]'):
[
[[1, 3, 4], [1, 4]], //array 1
[[5, 4, 3, 2], [5, 3]], //array 2
]
1* combination array 2* new array //↓new combinations
↓ ↓ //↓for the next iteration
│
array NAN*:
Combinations:
- [] │ -> []
│
array 1: ┌──────────────────────────────────┘
│
Combinations: v
- [] + [1, 3, 4] │ -> [[1, 3, 4]]
- [] + [1, 4] │ -> [[1, 4]]
│
array 2: ┌──────────────────────────────────┘
│
Combinations: v
- [[1, 3, 4]] + [5, 4, 3, 2] │ -> [[1, 3, 4], [5, 4, 3, 2]]
- [[1, 3, 4]] + [5, 3] │ -> [[1, 3, 4], [5, 3]]
- [[1, 4]] + [5, 4, 3, 2] │ -> [[1, 4], [5, 4, 3, 2]]
- [[1, 4]] + [5, 3] │ -> [[1, 4], [5, 3]]
//↑ All combinations here
* NAN:不是数字
正如您在上面的示例中看到的那样,我们现在拥有所有组合,其长度与我们拥有的所有数组的数量相同(4 个组合,长度为 2 个元素)。
如上例中获取组合的代码为:
//for循环确保我们得到每个组合所需的长度 //(我们拥有的数组数量。这里是2) for ($count = 0, $length = count($data); $count //1* 组合数组 foreach ($data[$count] as $v2) //2* 新数组 $tmp[] = array_merge($v1, [$v2]); //创建新的组合 $组合 = $tmp; //为下一次迭代分配新的组合
在您的具体示例中生成此数组:
Array
(
[0] => Array //Combination 1
(
[0] => Array
(
[0] => 1
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 2
)
)
[1] => Array //Combination 2
(
[0] => Array
(
[0] => 1
[1] => 3
[2] => 4
)
[1] => Array
(
[0] => 5
[1] => 3
)
)
[2] => Array //Combination 3
(
[0] => Array
(
[0] => 1
[1] => 4
)
[1] => Array
(
[0] => 5
[1] => 4
[2] => 3
[3] => 2
)
)
[3] => Array //Combination 4
(
[0] => Array
(
[0] => 1
[1] => 4
)
[1] => Array
(
[0] => 5
[1] => 3
)
)
)
数组交集
现在我们已经有了所有组合,我们可以使用 array_map()
遍历组合数组并获得每个组合的 array_intersect()
。而且由于我们不知道需要多少个数组进行交集,所以我们只使用call_user_func_array()
,例如
$intersections = array_map(function($v)
//intersection of each combination, which we created
return call_user_func_array("array_intersect", $v);
, $combinations);
完整代码:
<?php
$array1 = [[1, 3, 4], [1, 4]];
$array2 = [[5, 4, 3, 2], [5, 3]];
function getIntersections($data = [])
$combinations = [[]];
for ($count = 0, $length = count($data); $count < $length; $count++)
$tmp = [];
foreach ($combinations as $v1)
foreach ($data[$count] as $v2)
$tmp[] = array_merge($v1, [$v2]);
$combinations = $tmp;
$intersections = array_map(function($v)
return call_user_func_array("array_intersect", $v);
, $combinations);
return $intersections;
$intersections = getIntersections([$array1, $array2]);
print_r($intersections);
?>
输出:
Array
(
[0] => Array //Intersection of: [1, 3, 4] && [5, 4, 3, 2]
(
[1] => 3
[2] => 4
)
[1] => Array //Intersection of: [1, 3, 4] && [5, 3]
(
[1] => 3
)
[2] => Array //Intersection of: [1, 4] && [5, 4, 3, 2]
(
[1] => 4
)
[3] => Array //Intersection of: [1, 4] && [5, 3]
(
)
)
【讨论】:
【参考方案2】:这个foreach
正在解决我的问题
$array1= array(array("1","3","4"),array("1","4"));
$array2= array(array("5","4","3","2"),array("5","3"));
$result = array();
echo "<pre>";
foreach($array1 as $array1)
foreach($array2 as $array3)
print_r($array3);
$result[] = array_intersect($array1,$array3);
print_r($result);
如果你有更好的解决方案,请改进它
【讨论】:
以上是关于如何获得多个多维数组的所有可能交集?的主要内容,如果未能解决你的问题,请参考以下文章