Combining arrays based on key value

I have two arrays of arrays with the id key, and I would like to combine the data together based on this array key and the key value. The data will look something like this:

  $color = [ ['id' => 1, 'color' => 'red'], ['id' => 2, 'color' => 'green'], ['id' => 3, 'color' => 'blue'], ]; $size = [ ['id' => 1, 'size' => 'SM'], ['id' => 2, 'size' => 'XL'], ['id' => 3, 'size' => 'MD'], ['id' => 4, 'size' => 'LG'], ]; $combined = [ ['id' => 1, 'color' => 'red', 'size' => 'SM'], ['id' => 2, 'color' => 'green', 'size' => 'XL'], ['id' => 3, 'color' => 'blue', 'size' => 'MD'], ['id' => 4, 'size' => 'LG'], ]; 

Is there a particularly effective feature or trick to handle something like that? Or should I just scroll through the elements of one array and push the contents to another?

I also use Laravel, and the data is the result of an eloquent query, so I can also use collections if it makes the code cleaner.

+5
source share
7 answers

You can use array_replace_recursive to combine arrays in your specific situation.

 $color = array( array('id' => 1, 'color' => 'red'), array('id' => 2, 'color' => 'green'), array('id' => 3, 'color' => 'blue'), ); $size = array( array('id' => 1, 'size' => 'SM'), array('id' => 2, 'size' => 'XL'), array('id' => 3, 'size' => 'MD'), array('id' => 4, 'size' => 'LG'), ); $merged = array_replace_recursive($color, $size); 

Output:

 array(4) { [0]=> array(3) { ["id"]=> int(1) ["color"]=> string(3) "red" ["size"]=> string(2) "SM" } [1]=> array(3) { ["id"]=> int(2) ["color"]=> string(5) "green" ["size"]=> string(2) "XL" } [2]=> array(3) { ["id"]=> int(3) ["color"]=> string(4) "blue" ["size"]=> string(2) "MD" } [3]=> array(2) { ["id"]=> int(4) ["size"]=> string(2) "LG" } } 

Note. I used the traditional array layout because my version of PHP does not yet support the new one :)

Second option

You can also use array_map . This will allow you to add as many arrays as you want, with a little tweaking.

 $merged = array_map(function ($c, $s) { return array_merge($c, $s); }, $color, $size); var_dump($merged); // See output above 
+1
source

Use array_replace_recursive for an easy and quick way.

 array_replace_recursive($color, $size) 
+7
source

Better use a loop. First, calculate the maximum array, counting this number as a mileage. This will work.

+1
source

Try:

 $out = array(); foreach ($size as $key => $value){ if(!isset($color[$key])) { $color[$key] = array(); } $out[] = array_merge((array)$value,(array)$color[$key]); } 

Output:

 Array ( [0] => Array ( [id] => 1 [size] => SM [color] => red ) [1] => Array ( [id] => 2 [size] => XL [color] => green ) [2] => Array ( [id] => 3 [size] => MD [color] => blue ) [3] => Array ( [id] => 4 [size] => LG ) ) 
0
source

A simple nested loop will solve the goal.

 foreach($size as $key => $value1) { foreach($color as $value2) { if($value1['id'] === $value2['id']){ $size[$key]['title'] = $value2['color']; } } } echo '<pre>'; print_r($size); 

Output:

  Array ( [0] => Array ( [id] => 1 [size] => SM [title] => red ) [1] => Array ( [id] => 2 [size] => XL [title] => green ) [2] => Array ( [id] => 3 [size] => MD [title] => blue ) [3] => Array ( [id] => 4 [size] => LG ) ) 
0
source

I would suggest using laravel collections, as this question has a laravel tag.

 $color = collect( ['id' => 1, 'color' => 'red'], ['id' => 2, 'color' => 'green'], ['id' => 3, 'color' => 'blue'] ); $size = collect( ['id' => 1, 'size' => 'SM'], ['id' => 2, 'size' => 'XL'], ['id' => 3, 'size' => 'MD'], ['id' => 4, 'size' => 'LG'] ); $combined = $color->merge($size); 
0
source

Pure php solution - use array_replace_recursive , like this:

 array_replace_recursive( array_combine(array_column($color, "id"), $color), array_combine(array_column($size, "id"), $size) ); 

You should notice that array_replace_recursive joins arrays with keys. So, if you get such data from a database:

 $color = [ ['id' => 1, 'color' => 'red'], ['id' => 2, 'color' => 'red'] ]; $size = [ ['id' => 2, 'size' => 'SM'] ]; 

array_replace_recursive returns a damaged merge:

 $combined = [ ['id' => 2, 'color' => 'red', 'size' => 'SM'], ['id' => 2, 'color' => 'red'] ]; 

The solution is to combine array_replace_recursive with array_column and array_combine to combine arrays by their id field:

 array_replace_recursive( array_combine(array_column($color, "id"), $color), array_combine(array_column($size, "id"), $size) ); 

array_combine(array_column($color, "id"), $color) creates an associative array with id as keys.

So in your case it will return:

 $combined = [ 1 => ['id' => 1, 'color' => 'red', 'size' => 'SM'], 2 => ['id' => 2, 'color' => 'green', 'size' => 'XL'], 3 => ['id' => 3, 'color' => 'blue', 'size' => 'MD'], 4 => ['id' => 4, 'size' => 'LG'], ]; 
0
source

All Articles