Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine 2 associative arrays in php such that we do not overwrite any duplicate entries in all cases?

Tags:

arrays

php

I have two associative array which have many content same and so I want to combine those two arrays in such a way that if I have a in array 1 and a in array 2 than in array 3 I should have entries for both a's and not 1.

I have tried using array_merge but it would overwrite entries in 1st array if there are any duplicates in 2nd array, I have also tried using + but it gives me fatal error saying Fatal error: Unsupported operand types in /home/code.php then I tried doing

(array)$ar3 = (array)$ar1 +(array)$ar2 and it seems to add up. I want to know is this the correct way to do it and also why did initially I got fatal error and than it worked as I had already defined $ar3, $ar2, $ar1 as array types.

$orders = new Order(); 
$prospectOffers = $orders->getOrder($orderConfNumber); 
$prospectOffersResult = json_decode($prospectOffers,true); 
$shoppingBasket = $cart->getCartItems(); 
var_dump($prospectOffersResult); // Both are arrays 
var_dump($shoppingBasket); //Both are arrays 
(array)$result = (array)$prospectOffersResult+(array)$shoppingBasket;

Thanks.

like image 203
user260204 Avatar asked Jan 27 '10 16:01

user260204


1 Answers

$array1 + $array2 will return the union of the two arrays. If they are associative, values from the left operand will be preferred if keys collide. Therefore, this is not the solution you want as values will be lost.

There is nothing wrong with the statement provided both variables are understood as arrays. Your fatal error likely occurred because one variable was actually an object, and it's possible to mistake that using var_dump. By adding the type casts you forced PHP to coerce both variables to arrays. If one variable was an object, it would have this effect:

From the PHP.net Manual

"If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side."

Now having two arrays to add, PHP had nothing to panic about. Note that while casting the two operands of + was important, it was meaningless to cast the variable you were assigning to. The expression (array)$foo does not modify $foo, but rather returns a new value. This may not be intuitive from languages that require you to declare variables, but PHP is not such a language.

On your other issue, you cannot have two of the same key in an array. This would make it impossible to index the array as the correct value to return would become ambiguous. If you wish to combine two arrays in a lossless manor, you will have to use a more complicated data structure.

My suggestion is to use an array of arrays, where:

$a1 = array('a' => 1, 'b' => 2, 'c' => 3);
$a2 = array('a' => 3, 'b' => 2, 'd' => 2);

Will become:

$a3 = array(
    'a' => array(1, 3),
    'b' => array(2, 2),
    'c' => array(3),
    'd' => array(2)
);

And the ordering is not determined. The only notable change to the structure is that all first values are arrays, allowing values of duplicate keys to be accumulated. This function does the task and might do with a better name:

// array(array) lossless_array_merge([$array1 [, $array2 [, $...]]])

function lossless_array_merge() {
  $arrays = func_get_args();
  $data = array();
  foreach ($arrays as $a) {
    foreach ($a as $k => $v) {
      $data[$k][] = $v;
    }
  }
  return $data;
}
like image 125
erisco Avatar answered Nov 04 '22 09:11

erisco