Dwza
Dwza

Reputation: 6565

Merge two 2d arrays and remove duplicate rows

I searched a lot of SOF threads and no one seems to stick to my problem. What's kind of wired because this should be a well discussed question :)

Maybe I'm seeking for the wrong thing...

Scenario:

I have 2 arrays

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

and

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

My goal is

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

I really don't care about the order inside the array(s) but I want to merge both into one, without having duplicates.

I tried array_merge and array_merge_recursive. No one works. Probably because the functions doesn't know the identifier which identifies each entry. Is there an easy solution or do I really have to create an own method/function for this?

Maybe there is a closure that I could use?

Upvotes: 0

Views: 349

Answers (5)

user594138
user594138

Reputation:

I don't know how performant this is, but just using phps array-manipulation functions I get:

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",
     ],
]

Upvotes: 1

AbraCadaver
AbraCadaver

Reputation: 78994

If you index them on unique id then just add them. The result will be indexed on id which is convenient:

$result = array_column($a, null, 'id') + array_column($b, null, 'id');

Upvotes: 1

Progrock
Progrock

Reputation: 7485

Here's an approach at hashing each array with serialize after a key sort:

<?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));

Output:

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',
    ),
  )

Upvotes: 1

Vantiya
Vantiya

Reputation: 627

You can do this with very simple inbuilt function of PHP

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

The output of the print_r is

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
        )

)

Upvotes: 3

beasst
beasst

Reputation: 109

$temp = array_merge($b, $a);
foreach ($temp as $v) {
    $c[$v['id']] = $v;
}

If it finds the same id, the element will be overwritten in $c

Upvotes: 1

Related Questions