1

I need to merge associative arrays and group by the name. Say I have such 3 arrays:

ARRAY1
    "/path/file.jpg"  =>  2, 
    "/path/file2.bmp" =>  1,
    "/file3.gif"      => 5,

ARRAY2
    "/path/file.jpg"  =>  1, 
    "/path/file2.bmp" =>  1,
    "/file3.gif"      => 0,

ARRAY3
    "/path/file.jpg"  =>  1, 
    "/path/file2.bmp" =>  1,

I need to merge these arrays to one and group them by filepath and have result of sum of their values. Something like:

SELECT filename, SUM(val) FROM files
GROUP BY filename

But with multiple input arrays. Arrays are short (around 20 elements max). Each array might have different size.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
yosh
  • 3,245
  • 7
  • 55
  • 84

3 Answers3

2

[EDIT: I adapted the function (as suggested by John Green) to use func_get_args so you don't need to put all the seperate arrays in one array before you can use it.]

I think you could use the following function.

mergeArrays()
{
    $return = array();
    $arrays = func_get_args();
    foreach ($arrays as $array) {
        foreach ($array as $key => $val) {
            if (array_key_exists($key, $array) {
                $return[$key] += $val;
            } else {
                $return[$key] = $val;
            }
        }
    }
    return $return;
}
hoppa
  • 3,011
  • 18
  • 21
1

one possible way

$rtn = array();
foreach ($array1 as $key=>$val)
{
  $rtn[$key]+=$val;
}

foreach ($array2 as $key=>$val)
{
  $rtn[$key]+=$val;
}

foreach ($array2 as $key=>$val)
{
  $rtn[$key]+=$val;
}

the above will assign the filename, SUM(val) as an associative array into $rtn

ajreal
  • 46,720
  • 11
  • 89
  • 119
  • Works perfect. Fits my situation very well :) just added array_key_exists($key,$resultgarray) condition to get rid of notices. Thanks! – yosh Aug 10 '11 at 12:48
  • you can use `if (!isset($rtn[$key])) { $rtn[$key] = 0; }` – ajreal Aug 10 '11 at 12:51
1

You can use a RecursiveArrayIterator

$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($paths));
foreach ($iterator as $path => $value) {
    $summed[$path] = isset($summed[$path]) ? $summed[$path] + $value : $value;
}
print_r($summed);

or array_walk_recursive and a Closure

$summed = array();
array_walk_recursive($paths, function($value, $path) use (&$summed) {
    $summed[$path] = isset($summed[$path]) ? $summed[$path] + $value : $value;
});

Both will give

Array
(
    [/path/file.jpg] => 4
    [/path/file2.bmp] => 3
    [/file3.gif] => 5
)
Gordon
  • 312,688
  • 75
  • 539
  • 559