У меня есть два массива на 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()
. Но как я могу получить все возможные пересечения нескольких многомерных массивов?
Этот 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);
Если у вас есть лучшее решение, то PLZ улучшить его
Здесь мы создаем массив, содержащий все комбинации массивов, поэтому мы можем позже взять пересечения этих массивов.
Сначала нам нужно создать все возможные комбинации массивов. Который:
c array 1 * c array 2 *... * c array 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 элемента).
Код для получения комбинаций, как показано в приведенном выше примере, следующий:
//The for loop makes sure we get the desired length of each combination //(The amount of arrays which we have. Here 2) for ($count = 0, $length = count($data); $count < $length; $count++) { $tmp = []; foreach ($combinations as $v1) { //1* combinations array foreach ($data[$count] as $v2) //2* new array $tmp[] = array_merge($v1, [$v2]); //Creating new combinations } $combinations = $tmp; //Assigning the new combinations for the next iteration }
Что в вашем конкретном примере генерирует этот массив:
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]
(
)
)