Recursive merge php

I need to combine some arrays in some other way, and I'm using array_merge_recursive. However, there is something that I need to change, and I do not know how to do it. Here is a quote from php.net

If, however, the arrays have the same digital key, a later value will not overwrite the original value, but will be added.

I want this value NOT to be added, I do not want to add the exact values ​​to the new array. I hope you understand this.

Example:

$array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other'] = 'key2'; 

If I use array_merge_recursive, this will result in the following:

 Array ( [some] => Array ( [other] => Array ( [0] => key [1] => key2 ) ) ) 

I want it to match the same result, not add it. Yes, I know, you would say, and then use array_merge, but it does not work either. If I use this:

 $array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other2'] = 'key2'; print_r(array_merge($array, $array2)); 

It will remove $ array [some] [other] from the list and leave only $ array [some] [other2]. I do not know which is better, since no one does it better.

+7
source share
5 answers

try it

 <?php function mymerge(&$a,$b){ //$a will be result. $a will be edited. It to avoid a lot of copying in recursion foreach($b as $child=>$value){ if(isset($a[$child])){ if(is_array($a[$child]) && is_array($value)){ //merge if they are both arrays mymerge($a[$child],$value); } //else ignore, you can add your own logic, ie when 1 of them is array } else $a[$child]=$value; //add if not exists } //return $a; } 
+5
source

I wrote a merge class for it:

 <?php class ArrayMerge { /** * @param array $a * @param array $b * * @return array */ public function merge ( $a, $b ) { foreach ( $b as $k => $v ) { if ( is_array( $v ) ) { if ( isset( $a[ $k ] ) ) { if ( $this->isDeep( $v ) ) { $a[ $k ] = $this->merge( $a[ $k ], $v ); } else { $a[ $k ] = array_merge( $a[ $k ], $v ); } } else { $a[ $k ] = $v; } } else { $a[ $k ] = $v; } } return $a; } /** * @param array $array * * @return bool */ private function isDeep ( $array ) { foreach ( $array as $elm ) { if ( is_array( $elm ) ) { return TRUE; } } return FALSE; } } 
+1
source

I started with the RiaD version and added object handling. The need for testing and feedback

 function recursiveMerge(&$a,$b){ //$a will be result. $a will be edited. It to avoid a lot of copying in recursion if(is_array($b) || is_object($b)){ foreach($b as $child=>$value){ if(is_array($a)){ if(isset($a[$child])) recursiveMerge($a[$child],$value); else $a[$child]=$value; } elseif(is_object($a)){ if(isset($a->{$child})) recursiveMerge($a->{$child},$value); else $a->{$child}=$value; } } } else $a=$b; } 
+1
source

Another option: array_merge_deep from drupal:

 function array_merge_deep($arrays) { $result = array(); foreach ($arrays as $array) { foreach ($array as $key => $value) { // Renumber integer keys as array_merge_recursive() does. Note that PHP // automatically converts array keys that are integer strings (eg, '1') // to integers. if (is_integer($key)) { $result[] = $value; } // Recurse when both values are arrays. elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) { $result[$key] = array_merge_deep(array($result[$key], $value)); } // Otherwise, use the latter value, overriding any previous value. else { $result[$key] = $value; } } } return $result; } 
+1
source

For PHP> = 5.3 just use array_replace_recursive

+1
source

All Articles