1

I need a custom array_replace_recursive($array, $array1) method which does what the original array_replace_recursive($array, $array1) method does except that for indexed array it should use the array in the second array and overwrite the first array recursively.

example:

$a = array (
    'a' => array(1,2,3),
    'b' => array('a' => 1, 'b' => 2, 'c' => 3)
);  

$b = array (
    'a' => array(4),
    'b' => array('d' => 1, 'e' => 2, 'f' => 3)
); 

$c = array_replace_recursive($a, $b);

current behaviour:

$c = array (
    'a' => array(4,2,3),
    'b' => array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 1, 'e' => 2, 'f' => 3)
); 

desired behaviour:

$c = array (
    'a' => array(4),
    'b' => array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 1, 'e' => 2, 'f' => 3)
); 

as you can see element 'a' is an indexed array so the element in the second array has overwritten the element in the first array. element 'b' is an associative array so it maintains the original behaviour.

Abul Fayes
  • 117
  • 5

2 Answers2

1

Below worked for me:

<?php

/**
 * This method finds all the index arrays in array2 and replaces array in array1. it checks for indexed arrays recursively only within associative arrays.
 * @param $array1
 * @param $array2
 */

function customMerge(&$array1, &$array2) {
    foreach ($array2 as $key => $val) {
        if(is_array($val)) {
            if(!isAssoc($val)) {
                if($array1[$key] != $val) {
                    $array1[$key] = $val;
                }
            } else {
                $array1_ = &$array1[$key];
                $array2_ = &$array2[$key];
                customMerge($array1_, $array2_);
            }
        }
    }

}

function isAssoc($arr)
{
    return array_keys($arr) !== range(0, count($arr) - 1);
}

$a = array (
    'a' => array(1,2,3),
    'b' => array('a' => 1, 'b' => 2, 'c' => 3, 'g' => array(
        4,5,6
    ))
);

$b = array (
    'a' => array(4),
    'b' => array('d' => 1, 'e' => 2, 'f' => 3, 'g' => array(
        7
    ))
);

$c = array_replace_recursive($a, $b); // first apply the original method


$expected = array (
    'a' => array(4),
    'b' => array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 1, 'e' => 2, 'f' => 3, 'g'=> array(
        7
    )),
);

$d = $c; // create copy

customMerge($d, $b); // do the custom merge

echo $d == $expected;
Abul Fayes
  • 117
  • 5
0

The isAssoc() method in the first answer of this post is what your looking for:
How to check if PHP array is associative or sequential?

That method will check if the array is index and return true if it's the case.

Community
  • 1
  • 1
Mash
  • 1,339
  • 7
  • 8
  • The array type is only a minor part of the problem, it is the custom array_replace_recursive described that I need. – Abul Fayes Aug 14 '13 at 08:36
  • If I read this right, you want to merge associative array, and completely replace indexed array? – Mash Aug 14 '13 at 13:34