Пересечение многомерного массива переменного размера

У меня есть многомерный массив, который похож на это:

Array
(
[0] => Array
    (
        [0] => Array
            (
                [id] => 3
            )

        [1] => Array
            (
                [id] => 1
            )

        [2] => Array
            (
                [id] => 2
            )

        [3] => Array
            (
                [id] => 5
            )

        [4] => Array
            (
                [id] => 4
            )

    )

[1] => Array
    (
        [0] => Array
            (
                [id] => 1
            )

        [1] => Array
            (
                [id] => 3
            )

        [2] => Array
            (
                [id] => 4
            )

        [3] => Array
            (
                [id] => 5
            )

    )

[2] => Array
    (
        [0] => Array
            (
                [id] => 3
            )

    )

)

Я должен найти способ возвратить пересекающееся значение. В этом случае это было бы

[id] => 3

Длина массива могла отличаться, таким образом, я не могу просто использовать array_intersect ().

5
задан Jakob Løkke Madsen 13 September 2012 в 16:22
поделиться

3 ответа

Это было бы просто, если бы Ваши массивы содержали только целые числа, но так как они содержат другой массив, это становится немного сложнее. Но так и должно быть:

function custom_intersect($arrays) {
    $comp = array_shift($arrays);
    $values = array();

    // The other arrays are compared to the first array:
    // Get all the values from the first array for comparison
    foreach($comp as $k => $v) {
        // Set amount of matches for value to 1.
        $values[$v['id']] = 1;
    }

    // Loop through the other arrays
    foreach($arrays as $array) {
        // Loop through every value in array
        foreach($array as $k => $v) {
            // If the current ID exists in the compare array
            if(isset($values[$v['id']])) {
                // Increase the amount of matches
                $values[$v['id']]++;
            }
        }
    }

    $result = array();

    // The amount of matches for certain value must be
    // equal to the number of arrays passed, that's how
    // we know the value is present in all arrays.
    $n = count($arrays) + 1;
    foreach($values as $k => $v) {
        if($v == $n) {
            // The value was found in all arrays,
            // thus it's in the intersection
            $result[] = $v;
        }
    }
    return $result;
}

Использование:

$arrays = array(
    array(array('id' => 3), array('id' => 1), array('id' => 2), array('id' => 5), array('id' => 4)),
    array(array('id' => 1), array('id' => 3), array('id' => 4), array('id' => 5)),
    array(array('id' => 3))
);

print_r(custom_intersect($arrays));

Результат:

Array
(
    [0] => 3
)

Эта функция не идеальна: если у вас в одном массиве есть дубликаты идентификаторов, то она не будет работать. Для того, чтобы сделать значения массивов уникальными, сначала потребуется немного больше кода, но в вашем случае это, скорее всего, сработает.

.
4
ответ дан 14 December 2019 в 04:39
поделиться

Как упоминалось в одном из комментариев сайта php.net (функция array_intersect)

$a = array(1,2,3,4,5,2,6,1);  /* repeated elements --> $a is not a set */
$b = array(0,2,4,6,8,5,7,9,2,1);  /* repeated elements --> $b is not a set */

$ua = array_merge(array_unique($a));  /* now, $a is a set */
$ub = array_merge(array_unique($b));  /* now, $b is a set */

$intersect = array_merge(array_intersect($ua,$ub));

Это вернёт этот массив:

Array
(
    [0] => 1
    [1] => 2
    [2] => 4
    [3] => 5
    [4] => 6
)
0
ответ дан 14 December 2019 в 04:39
поделиться

Вы можете использовать array_uintersect () , чтобы получить пересечение массивов с помощью специальной функции сравнения. Вы должны вызвать его с помощью call_user_func_array () , поскольку он ожидает каждый массив как отдельный аргумент:

//build list of parameters for array_uintersect()
$params = array_merge($input, array('compare_func'));

$result = call_user_func_array('array_uintersect', $params);

function compare_func($a, $b) {
    return $a['id'] - $b['id'];   
}

Вы не можете просто вызвать array_intersect () с помощью call_user_func_array () , потому что кажется, что он сравнивает массивы, сравнивая их строковое представление (которое всегда будет «Массив»).

3
ответ дан 14 December 2019 в 04:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: