8

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.

6
  • 1
    How deep is the nesting in your array? Just one level? Commented Aug 7, 2011 at 20:47
  • 1
    So tell us what your result should be? Commented Aug 7, 2011 at 20:48
  • Well It may be unlimited.I won't use it only for 1 level. Commented Aug 7, 2011 at 20:48
  • @scube the result should be (if using array_merge) NOT to remove the prevous items from the first array. The second example shows: Array ( [some] => Array ( [other2] => key2 ) ) And I want to show: Array ( [some] => Array ( [other] => key [other2] => key2 ) ) Commented Aug 7, 2011 at 20:49
  • 1
    @Alex: What do you expect for executing that: $array = array( 'some' => array( 'other' => 'key', ), ); $array2['some']['other'] = 'key2'; when using array_merge_recursive? Commented Aug 7, 2011 at 20:54

5 Answers 5

7

For PHP >= 5.3 just use array_replace_recursive

Sign up to request clarification or add additional context in comments.

Comments

5

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;
}

1 Comment

This answer may not be correct probably. Because I tested your answer and results is not like what I expected. Can you please take a look at this link ? link
2

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;
}

Comments

1

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;
    }

}

Comments

1

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;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.