Как получить все возможные пересечения нескольких многомерных массивов?

1

У меня есть два массива на 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(). Но как я могу получить все возможные пересечения нескольких многомерных массивов?

Теги:
arrays
multidimensional-array
array-intersect

2 ответа

1
Лучший ответ

Этот 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 улучшить его

3

Здесь мы создаем массив, содержащий все комбинации массивов, поэтому мы можем позже взять пересечения этих массивов.

Комбинации массивов

Сначала нам нужно создать все возможные комбинации массивов. Который:

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]
        (
        )

)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню