Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array_merge_recursive gives me repeat data, how to remove it

Tags:

arrays

php

I have the following 2 arrays that I'm trying to merge recursively so that I don't lose data, but I also don't want any data repeated.

$a = array(
    'group1' => array(
        'names' => array(
            'g1name1',
            'g1name2'
         )
    ),
    'group2' => array(
         'names' => array(
             'g2name1'
         )
    )
);

$b = array(
    'group1' => array(
        'names' => array(
            'g1name1',
            'g1name3'
        ),
        'extras' => array(
            'g1extra1'
        )
    ),
    'group3' => array(
        'names' => array(
            'g3name1'
        )
    )
);

I'm using array_merge_recursive($a, $b); which works fine for group2 and group3 because they exist in either $a or $b, but group1 is giving me a problem because it has some duplicate data in both $a and $b. This is what I'm getting after I merge recursively. Notice that in names, g1name is listed twice, once from $a and once from $b.

'group1' => 
    array
      'names' => 
        array
          0 => string 'g1name1'
          1 => string 'g1name2'
          2 => string 'g1name1'
          3 => string 'g1name3'
      'extras' => 
        array
          0 => string 'g1extra1'
          1 => string 'g1extra2'
  'group2' => ....
  'group3' => ....

I tried array_unique like this array_unique(array_merge_recursive($a, $b)) but it's giving me strange results (doesn't fix the repeat problem and deletes group2 and group3 entirely).

like image 986
sameold Avatar asked Dec 23 '11 17:12

sameold


3 Answers

Use array_replace_recursive instead of array_merge_recursive.

like image 178
bavo Avatar answered Nov 06 '22 15:11

bavo


The the following should work for you:

array_walk($arr, function(&$data, $key) {
    foreach ($data as &$arr) {
        $arr = array_values(array_unique($arr));
    }
});

Result:

Array
(
    [group1] => Array
        (
            [names] => Array
                (
                    [0] => g1name1
                    [1] => g1name2
                    [2] => g1name3
                )
            [extras] => Array
                (
                    [0] => g1extra1
                )
        )
    [group2] => Array
        (
            [names] => Array
                (
                    [0] => g2name1
                )
        )
    [group3] => Array
        (
            [names] => Array
                (
                    [0] => g3name1
                )
        )
)
like image 8
Tim Cooper Avatar answered Nov 06 '22 16:11

Tim Cooper


Sadly, array_replace_recursive (PHP 5.3.0)­Docs does not work (Demo).

Luckily Tim Cooper pointed that out and made some suggestion. I was not very creative with my new suggestion, so it's highly influenced by his solution:

$result = array_merge_recursive($a, $b);

array_walk($result, function(&$v) {
    $v = array_map('array_unique', $v);
});

New Demo

like image 2
hakre Avatar answered Nov 06 '22 15:11

hakre