1

I have an array like this:

$months = Array ( 
"may" =>
    Array (
        "A" => 101,
        "B" => 33,
        "C" => 25
    ),
"june" =>
    Array (
        "A" => 73,
        "B" => 11,
        "D" => 32
    ),
"july" =>
    Array (
        "A" => 45,
        "C" => 12
    )
);

I want to get an array like this:

Array ( ['all'] => 
            Array (
           [A] => 219
           [B] => 44
           [C] => 37
           [D] => 32
          )
    )

I wrote a function with 2 parameters (the two arrays to join) and it worked, but I fail, when I try to make it possible to call it with more than 2 arrays. I tried to do it via recursion:

function array_merge_elements(){
    $arg_list = func_get_args();
    $array1 = $arg_list[0];
    $array2 = $arg_list[1];
    $keys = array_unique(array_merge(array_keys($array1), array_keys($array2)));
    $result_array = array();
    foreach($keys as $key) {
        $result_array["$key"] = 0;
        if(!empty($array1[$key])) {
            $result_array["$key"] += $array1[$key];
        }
        if(!empty($array2[$key])) {
            $result_array["$key"] += $array2[$key];
        }
    }
    if(func_num_args() == 2) {
        return $result_array;
    } else {
        unset($arg_list[0]);
        unset($arg_list[1]);
        return array_merge_elements($result_array, $arg_list);
    }
}

The problem seems to be, that calling the function with (array1, arglist) is not the same as calling the function with (array1, array2, array3) etc.

2
  • why can't you declare function as array_merge_elements($array1,$array2)? Commented Jun 21, 2011 at 10:46
  • I can, but i wanted to be able to say array_merge_elements($array1,$array2, $array3) as well. Commented Jun 21, 2011 at 11:47

3 Answers 3

3

What's wrong with just doing (demo)

foreach ($months as $month) {
    foreach ($month as $letter => $value) {
        if (isset($months['all'][$letter])) {
            $months['all'][$letter] += $value;
        } else {
            $months['all'][$letter] = $value;
        }
    }
}
print_r($months['all']);

or - somewhat less readable due to the ternary operation (demo):

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($months));
foreach ($iterator as $letter => $value) {
    isset($months['all'][$letter])
        ? $months['all'][$letter] += $value
        : $months['all'][$letter] = $value;
}
print_r($months['all']);
Sign up to request clarification or add additional context in comments.

2 Comments

Recursion is not the way to solve the problem. BTW the if...else... construct is redundant - just using '$months['all'][$letter] += $value;' would suffice (although it will generate warnings)
@symcbean Recursive Iterators are fine for this problem. Also, if the += code raises Notices (which it does), it isnt redundant to check for that condition.
1

If you'd split off the first two entries of your found arguments; you can use the resulting array in a call with this function: Call_user_func_array

Comments

0

for fellow googlers out there, here's the answer to the original question

Assume we have a function that adds two arrays together:

function array_plus($a, $b) {
    foreach($b as $k => $v)
        $a[$k] = (isset($a[$k]) ? $a[$k] : 0) + $v;
    return $a;
}

this is how to apply this function to a set of arrays

$sum = array_reduce($months, 'array_plus', array());

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.