Мне нужно объединить некоторые массивы по-другому, и я использую array_merge_recursive. Однако есть что-то, что мне нужно изменить, и я не знаю, как это сделать. Вот цитата из php.net
Если, однако, массивы имеют один и тот же числовой ключ, более позднее значение не будет перезаписывать исходное значение, но будет добавлено.
Я хочу это значение, НЕ добавляемое, я хочу не добавлять точные значения в новый массив. Надеюсь, вы это поняли.
Пример:
$array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other'] = 'key2';
Если я использую array_merge_recursive, это приведет к следующему:
Array ( [some] => Array ( [other] => Array ( [0] => key [1] => key2 ) ) )
Я хочу, чтобы он совпал с тем же результатом, а не добавлял его. Да, я знаю, вы бы сказали, а затем используйте array_merge, но он тоже не работает. Если я использую это:
$array = array( 'some' => array( 'other' => 'key', ), ); $array2 = array(); $array2['some']['other2'] = 'key2'; print_r(array_merge($array, $array2));
Он удалит $ array [some] [other] из списка и оставит только $ array [some] [other2]. Я не знаю, что лучше, так как никто не делает это лучше.
попробуй это
<?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, ie when 1 of them is array } else $a[$child]=$value; //add if not exists } //return $a; }
Я написал для этого класс слияния:
<?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; } }
Я начал с версии RiaD и добавил обработку объекта. Необходимость тестирования и обратной связи
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; }
Другой вариант: array_merge_deep
из 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; }
Для PHP> = 5.3 просто используйте array_replace_recursive