2

I have this function (I got as the answer to this question) that merges an array like so:

#Functions

function readArray( $arr, $k, $default = 0 ) {
    return isset( $arr[$k] ) ? $arr[$k] : $default ;
}

function merge( $arr1, $arr2 ) {
    $result = array() ;
    foreach( $arr1 as $k => $v ) {
        if( is_numeric( $v ) ) {
            $result[$k] = (int)$v + (int) readArray( $arr2, $k ) ;
        } else {
            $result[$k] = merge( $v, readArray($arr2, $k, array()) ) ;
        }
    }
    return $result ;
}

#Usage

$basketA = array( "fruit" => array(), "drink" => array() ) ;
$basketA['fruit']['apple'] = 1;
$basketA['fruit']['orange'] = 2;
$basketA['fruit']['banana'] = 3;
$basketA['drink']['soda'] = 4;
$basketA['drink']['milk'] = 5;

$basketB = array( "fruit" => array(), "drink" => array() ) ;
$basketB['fruit']['apple'] = 2;
$basketB['fruit']['orange'] = 2;
$basketB['fruit']['banana'] = 2;
$basketB['drink']['soda'] = 2;
$basketB['drink']['milk'] = 2;

$basketC = merge( $basketA, $basketB ) ;
print_r( $basketC ) ;

#Output

Array
(
    [fruit] => Array
        (
            [apple] => 3
            [orange] => 4
            [banana] => 5
        )

    [drink] => Array
        (
            [soda] => 6
            [milk] => 7
        )

)

OK this works with 1 flaw I cannot figure out how to fix: if $arr1 is missing something that $arr2 has, it should just use the value from $arr2 but instead omits it all together:

#Example

$basketA = array( "fruit" => array(), "drink" => array() ) ;
$basketA['fruit']['apple'] = 1;
$basketA['fruit']['orange'] = 2;
$basketA['fruit']['banana'] = 3;
$basketA['drink']['milk'] = 5;

$basketB = array( "fruit" => array(), "drink" => array() ) ;
$basketB['fruit']['apple'] = 2;
$basketB['fruit']['orange'] = 2;
$basketB['fruit']['banana'] = 2;
$basketB['drink']['soda'] = 2;
$basketB['drink']['milk'] = 2;

$basketC = merge( $basketA, $basketB ) ;
print_r( $basketC ) ;

#Output

Array
(
    [fruit] => Array
        (
            [apple] => 3
            [orange] => 4
            [banana] => 5
        )

    [drink] => Array
        (
            [milk] => 7
        )

)

Notice how [soda] is not in the new array because the first array did not have it.

How can I fix this?

1 Answer 1

2

Quick fix, change the merge() function to look like this:

function merge( $arr1, $arr2 ) {
    $result = array() ;
    foreach( $arr1 as $k => $v ) {
        if( is_numeric( $v ) ) {
            $result[$k] = (int)$v + (int) readArray( $arr2, $k ) ;
        } else {
            $result[$k] = merge( $v, readArray($arr2, $k, array()) ) ;
        }
    }
    foreach( $arr2 as $k => $v ) {
        if( is_numeric( $v ) ) {
            $result[$k] = (int)$v + (int) readArray( $arr1, $k ) ;
        } else {
            $result[$k] = merge( $v, readArray($arr1, $k, array()) ) ;
        }
    }
    return $result ;
}

Output:

Array
(
    [fruit] => Array
        (
            [apple] => 3
            [orange] => 4
            [banana] => 5
        )

    [drink] => Array
        (
            [soda] => 2
            [milk] => 7
        )
)

It's also worth noticing that array_merge_recursive() alone does almost the same:

$basketC = array_merge_recursive($basketA, $basketB);

Output:

Array
(
    [fruit] => Array
        (
            [apple] => Array
                (
                    [0] => 1
                    [1] => 2
                )

            [orange] => Array
                (
                    [0] => 2
                    [1] => 2
                )

            [banana] => Array
                (
                    [0] => 3
                    [1] => 2
                )

        )

    [drink] => Array
        (
            [milk] => Array
                (
                    [0] => 5
                    [1] => 2
                )

            [soda] => 2
        )
)

So if you wanted to know how many oranges are in $basketC, you would just have to do:

array_sum((array)$basketC['fruit']['orange']); // 4

This way you don't need to use any hackish, slow and unproved custom function.

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

1 Comment

This works, although i am surprised, looking at the code I would have thought it was merging them twice making the values doubled but I tested it and it works like it should. Thank you!!

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.