可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to merge some arrays in some different way and I use array_merge_recursive. However there is something that I need to change and I don't know how. Here is quote from php.net
If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.
I want this value, NOT to be appended, I want not to append exact values in the new array.Hope you've understood this.
Example:
$array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other'] = 'key2';
If I use array_merge_recursive It will result this:
Array ( [some] => Array ( [other] => Array ( [0] => key [1] => key2 ) ) )
I want if it matches the same result, not to append it.Yes I know, you would say, then use array_merge, but it doesn't work well, too. 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 don't know which is better, since no one makes it better.
回答1:
try this
<?php function mymerge(&$a,$b){ //$a will be result. $a will be edited. It's 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, i.e when 1 of them is array } else $a[$child]=$value; //add if not exists } //return $a; }
回答2:
I wrote my 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; } }
回答3:
I started from RiaD's version and added object handling. Need testing and feedback
function recursiveMerge(&$a,$b){ //$a will be result. $a will be edited. It's 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; }
回答4:
An other alternative, the 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 (e.g., '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; }
回答5:
For PHP >= 5.3 just use array_replace_recursive