85

I need to merge two arrays of objects into 1 array and remove duplicate email values.

How can I do that?

These are my sample arrays:

$array1 = [
    (object) ["email" => "gffggfg"],
    (object) ["email" => "[email protected]"],
    (object) ["email" => "wefewf"],
];
$array2 = [
    (object) ["email" => "[email protected]"],
    (object) ["email" => "wefwef"],
    (object) ["email" => "wefewf"],
];

My expected result is:

[
   (object) ['email' => 'gffggfg'],
   (object) ['email' => '[email protected]'],
   (object) ['email' => 'wefewf'],
   (object) ['email' => '[email protected]'],
   (object) ['email' => 'wefwef'],
]
0

8 Answers 8

216

You can combine the array_merge() function with the array_unique() function (both titles are pretty self-explanatory)

$array = array_unique (array_merge ($array1, $array2));
Sign up to request clarification or add additional context in comments.

5 Comments

well as i can see array_merge() seems not calculating duplicates so array_unique() is deprecated in my case or not !?
array_merge() doesn't add duplicate keys, but when you have duplicate values with different keys, it does add those
Should add mention of SORT_REGULAR and other options to avoid errors with converting types.
note: array_unique preserves keys, so for numerically indexed arrays if you need sequential keys, you can quickly rekey by wrapping with a call to array_values
Despite the flood of upvotes and the green tick on this concise answer, it is provably incorrect using the asker's sample data.
13

If I understand the question correctly:

 $a1 = Array(1,2,3,4);
 $a2 = Array(4,5,6,7);
 $array =  array_diff(array_merge($a1,$a2),array_intersect($a1,$a2));
 print_r($array);

return

Array
(
[0] => 1
[1] => 2
[2] => 3
[5] => 5
[6] => 6
[7] => 7
)

2 Comments

sorry i forgot about i have multilevel array not simple array
Not only does this unexplained answer not work with the asker's data, even if it did, it would not be efficient because it is making value-based comparisions. In PHP, key-based comparisons always execute faster.
8

I've been running some benchmarks of all the ways I can imagine of doing this. I ran tests on stacking lots of arrays of 10-20 string elements, resulting in one array with all unique strings in there. This sould be about the same for stacking just 2 arrays.

The fastest I've found was the simplest thing I tried.

$uniques = [];
foreach($manyArrays as $arr ) {
  $uniques = array_unique(array_merge($uniques, $arr));
}

I had branded this 'too naive to work', since it has to sort the uniques array every iteration. However this faster than any other method. Testing with 500.000 elements in manyArrays, each containing 10-20 strings om PHP 7.3.

A close second is this method, which is about 10% slower.

$uniques = [];
foreach($manyArrays as $arr ) {
  foreach($arr as $v) {
    if( !in_array($v, $uniques, false) ) {
      $uniques[] = $v;
    }
  }
}

The second method could be better in some cases, as this supports the 'strict' parameter of in_array() for strict type checking. Tho if set to true, the second option does become significantly slower than the first (around 40%). The first option does not support strict type checking.

1 Comment

How are you populating $manyArrays in the context of this task?
1

Faster solution:

function concatArrays($arrays){
    $buf = [];
    foreach($arrays as $arr){
        foreach($arr as $v){
            $buf[$v] = true;
        }
    }
    return array_keys($buf);
}


$array = concatArrays([$array1, $array2]);

2 Comments

How is a nested foreach faster than built-in functions. Do you have benchmarks?
Proof that this answer does not work with the asker's provided data: 3v4l.org/dp6tt
1

Because the email properties in the array of objects contain non-numeric values, you can temporarily assign first level keys (with array_column()) then merge the two arrays with the union operator (a function-less action).

If the temporary keys are disruptive to your next process, you can re-index the array with array_values().

Code: (Demo)

var_export(
    array_values(
        array_column($array1, null, 'email')
        + array_column($array2, null, 'email')
    )
);

Output:

array (
  0 => 
  (object) array(
     'email' => 'gffggfg',
  ),
  1 => 
  (object) array(
     'email' => '[email protected]',
  ),
  2 => 
  (object) array(
     'email' => 'wefewf',
  ),
  3 => 
  (object) array(
     'email' => '[email protected]',
  ),
  4 => 
  (object) array(
     'email' => 'wefwef',
  ),
)

"Merge and keep unique objects" will also work with a special flag.

Code: (Demo)

var_export(
    array_unique(
        array_merge($array1, $array2),
        SORT_REGULAR
    )
);
// same result as other snippet

Comments

0

Very old thread, but... OP's arrays contains objects. If I were op, I would declare a class that receives the sub arrays in the constructor with a __toString() function that returns the email. If op then makes his objects into instances of that class, array_unique should call __toString() when comparing

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0
<?php
   $array1 = array("yellow", "red", "green", "orange", "purple");
   $array2 = array("pink", "brown", "green", "orange", "red");
   $array = array_unique(array_merge($array1, $array2));
   print_r($array);
?>
 
Array
(
    [0] => yellow
    [1] => red
    [2] => green
    [3] => orange
    [4] => purple
    [5] => pink
    [6] => brown
)

Comments

-1

A little bit late answer, but I just found that the array union operator + does the job quite greatly (found here at the 3rd section).

$array1 + $array2 = $array //if duplicate found, the value in $array1 will be considered ($array2 value for array_merge, if keys clearly specified)

2 Comments

Not a good option to apply! You will get erroneous data if Array KEY is same even VALUE is different, eg: $array1 = Array( [0] => 0, [1] => 1, [2] => 2 ) $array2 = Array( [0] => 3 ) $array1 + $array2 = Array( [0] => 0, [1] => 1, [2] => 2 ) Better option will be array_unique (array_merge ($array1, $array2)) = Array( [0] => 0, [1] => 1, [2] => 2, [3] => 3 )
This does not result in a Union of array's values, see php.net

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.