Abul Fayes
Abul Fayes

Reputation: 147

php custom array_replace_recursive method

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.

Upvotes: 1

Views: 315

Answers (2)

Abul Fayes
Abul Fayes

Reputation: 147

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;

Upvotes: 1

Mash
Mash

Reputation: 1339

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.

Upvotes: 0

Related Questions