Объединить многомерный массив по ассоциативному значению - PullRequest
0 голосов
/ 11 октября 2019

Я искал много тем SOF, и никто, кажется, не придерживался моей проблемы. Что за проводка, потому что это должен быть хорошо обсужденный вопрос:)

Может быть, я ищу не ту вещь ...

Сценарий:

У меня есть 2 массива

$a = [ 
    ['id' => 5, 'name' => 'bruce'],
    ['id' => 7, 'name' => 'wayne']
];
// 2 elements

и

$b = [
    ['id' => 6, 'name' => 'chuck'],
    ['id' => 8, 'name' => 'norris'],
    ['id' => 7, 'name' => 'wayne'] //also exists in array $a
];
// 3 elements

Моя цель

$c = [
    ['id' => 6, 'name' => 'chuck'],
    ['id' => 8, 'name' => 'norris'],
    ['id' => 7, 'name' => 'wayne'],
    ['id' => 5, 'name' => 'bruce']
];
// 4 elements (no duplicates)

Мне действительно все равно, какой порядок внутри массива (s) но я хочу объединить оба в один без дубликатов.

Я пробовал array_merge и array_merge_recursive . Никто не работает. Возможно, потому что функции не знают идентификатора, который идентифицирует каждую запись. Есть ли простое решение или мне действительно нужно создать собственный метод / функцию для этого?

Может быть есть закрытие, которое я мог бы использовать?

Ответы [ 5 ]

3 голосов
/ 11 октября 2019

Вы можете сделать это с очень простой встроенной функцией PHP

$c = array_unique(array_merge($a,$b), SORT_REGULAR);
print_r( $c )

Выходные данные print_r:

Array
(
    [0] => Array
        (
            [id] => 5
            [name] => bruce
        )

    [1] => Array
        (
            [id] => 7
            [name] => wayne
        )

    [2] => Array
        (
            [id] => 6
            [name] => chuck
        )

    [3] => Array
        (
            [id] => 8
            [name] => norris
        )

)
1 голос
/ 11 октября 2019

Если вы индексируете их по уникальным id, просто добавьте их. Результат будет проиндексирован на id, что удобно:

$result = array_column($a, null, 'id') + array_column($b, null, 'id');
1 голос
/ 11 октября 2019

Вот подход к хэшированию каждого массива с сериализацией после сортировки ключа:

<?php

$a = [ 
    ['id' => 5, 'name' => 'bruce'],
    ['id' => 7, 'name' => 'wayne']
];

$b = [
    ['id' => 6, 'name' => 'chuck'],
    ['name' => 'wayne', 'id' => 7],
    ['id' => 8, 'name' => 'norris']
];
$merged = array_merge($a, $b);

foreach($merged as $k => $v) {
    ksort($v);
    $hashes[$k] = serialize($v);
}
$hashes = array_unique($hashes);
var_export(array_intersect_key($merged, $hashes));

Вывод:

array (
    0 => 
    array (
      'id' => 5,
      'name' => 'bruce',
    ),
    1 => 
    array (
      'id' => 7,
      'name' => 'wayne',
    ),
    2 => 
    array (
      'id' => 6,
      'name' => 'chuck',
    ),
    4 => 
    array (
      'id' => 8,
      'name' => 'norris',
    ),
  )
1 голос
/ 11 октября 2019

Я не знаю, насколько это эффективно, но просто используя функции манипуляции с массивами phps, я получаю:

>>> array_values(array_merge(array_combine(array_column($a, 'name'), $a), array_combine(array_column($b, 'name'), $b)));
=> [
     [
       "id" => 5,
       "name" => "bruce",
     ],
     [
       "id" => 7,
       "name" => "wayne",
     ],
     [
       "id" => 6,
       "name" => "chuck",
     ],
     [
       "id" => 8,
       "name" => "norris",
     ],
   ]
1 голос
/ 11 октября 2019
$temp = array_merge($b, $a);
foreach ($temp as $v) {
    $c[$v['id']] = $v;
}

Если он найдет тот же идентификатор, элемент будет перезаписан в $ c

...