14

Is there an array function in PHP that somehow does array_merge, comparing the values, ignoring the keys? I think that array_unique(array_merge($a, $b)) works, however I believe there must be a nicer way to do this.

eg.

$a = array(0 => 0, 1 => 1, 2 => 2);
$b = array(0 => 2, 1 => 3, 2 => 4);

resulting in:

$ab = array(0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4);

Please note that I don't care about the keys in $ab, however it would be nice if they were ascending, starting at 0 to count($ab)-1.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
ptmr.io
  • 2,115
  • 4
  • 22
  • 34
  • 7
    I don't think there is a nicer way to do this. `array_unique(array_merge($a, $b))` is actually a pretty elegant solution. – Ben Lee Jan 11 '11 at 17:50
  • 2
    It is good to note that this will only work if the keys are numeric or guaranteed to be unique between the two arrays, otherwise `array_merge` will overwrite. – Will Jan 11 '11 at 17:52

5 Answers5

26

The most elegant, simple, and efficient solution is the one mentioned in the original question...

$ab = array_unique(array_merge($a, $b));

This answer was also previously mentioned in comments by Ben Lee and doublejosh, but I'm posting it here as an actual answer for the benefit of other people who find this question and want to know what the best solution is without reading all the comments on this page.

orrd
  • 9,469
  • 5
  • 39
  • 31
  • Elegant and simple, yes, but only eventually most efficient. Copying and sorting an array won't become efficient until the array is big enough. – Ja͢ck Mar 24 '14 at 04:01
2
function umerge($arrays){
 $result = array();
 foreach($arrays as $array){
  $array = (array) $array;
  foreach($array as $value){
   if(array_search($value,$result)===false)$result[]=$value;
  }
 }
 return $result;
}
Community
  • 1
  • 1
Oliver A.
  • 2,870
  • 2
  • 19
  • 21
  • i will select this on as the correct answer, because it is a nice way to do it. However you wrote "reult" instead of result in line 5. Another way: array_merge(array_unique(array_merge($a, $b))); Thanks all. – ptmr.io Jan 11 '11 at 18:06
  • @doublejosh This will be more efficient until arrays become substantially big, ~400 elements. – Ja͢ck Mar 24 '14 at 04:00
  • 1
    @doublejosh Had to deal with 10.000+ item arrays and scripts running for 9:50 at a max execution time of 10:00. Well that was in 2011 and I'm glad I no longer have to deal with that kind of problems (new job / better servers). – Oliver A. Mar 31 '14 at 21:18
  • 2
    OMG. That's a lot of data to handle directly in PHP! – doublejosh Apr 11 '14 at 23:04
2

To answer the question as asked, for a general solution that also works with associative arrays while preserving keys, I believe that you will find this solution most satisfactory:

/**
 * array_merge_unique - return an array of unique values,
 * composed of merging one or more argument array(s).
 *
 * As with array_merge, later keys overwrite earlier keys.
 * Unlike array_merge, however, this rule applies equally to
 * numeric keys, but does not necessarily preserve the original
 * numeric keys.
 */
function array_merge_unique(array $array1 /* [, array $...] */) {
  $result = array_flip(array_flip($array1));
  foreach (array_slice(func_get_args(),1) as $arg) { 
    $result = 
      array_flip(
        array_flip(
          array_merge($result,$arg)));
  } 
  return $result;
}
danorton
  • 11,804
  • 7
  • 44
  • 52
-1

array_merge will ignore numeric keys, so in your example array_merge($a, $b) would give you $ab, there is no need to call array_unique().

if you have string keys (i.e. an associative array) use array_values() first:

array_merge(array_values($a), array_values($b));
Stephen
  • 18,597
  • 4
  • 32
  • 33
  • he wants the unique values though, so he needs to call `array_unique` – Will Jan 11 '11 at 17:55
  • where exactly does it say he only only wants unique values? just because he was using `array_unique` doesn't mean anything - he freely admitted he wasn't sure what to use, and the description makes no mention of wanting only unique entries. – Stephen Jan 11 '11 at 17:59
  • @Will, you are right, values must be unique @Stephen: sorry, it might have been confusing. solution is: array_merge(array_unique(array_merge($a, $b))); because the second array_merge sorts the key from 0 to 4! Thanks all! – ptmr.io Jan 11 '11 at 18:02
  • in that case, you don't need two `array_merge` calls - an `array_values` call is probably a better choice – Stephen Jan 11 '11 at 18:06
  • 1
    The original question's example does show that he's looking for the unique values. Calling array_values() before calling array_merge() doesn't actually do anything at all because array_merge() will renumber the array keys since the input arrays have numeric keys (see the array_merge() PHP docs). – orrd Mar 24 '14 at 02:32
-1
$a = array(0 => 0, 1 => 1, 2 => 2);
$b = array(0 => 2, 1 => 3, 2 => 4);

//add any from b to a that do not exist in a
foreach($b as $item){


    if(!in_array($item,$b)){
        $a[] = $item
    }

}

//sort the array
sort($a);
woot586
  • 3,906
  • 10
  • 32
  • 40