Мне нужно объединить ассоциативные массивы и группу по имени. Скажем, у меня есть 3 массива:
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,
Мне нужно объединить эти массивы в один и сгруппировать их по пути файла и получить результат суммы их значений. Что-то вроде:
SELECT filename, SUM(val) FROM files GROUP BY filename
Но с несколькими входными массивами. Массивы коротки (макс. 20 элементов). Каждый массив может иметь разный размер.
один из возможных способов
$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; }
вышесказанное присвоит filename, SUM(val)
как ассоциативный массив в $rtn
[EDIT: Я адаптировал функцию (как предложил Джон Грин) для использования func_get_args, поэтому вам не нужно размещать все отдельные массивы в одном массиве, прежде чем вы сможете ее использовать.]
Я думаю, вы могли бы использовать следующую функцию.
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; }
Вы можете использовать RecursiveArrayIterator
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($paths)); foreach ($iterator as $path => $value) { $summed[$path] = isset($summed[$path]) ? $summed[$path] + $value : $value; } print_r($summed);
или array_walk_recursive
и закрытие
$summed = array(); array_walk_recursive($paths, function($value, $path) use (&$summed) { $summed[$path] = isset($summed[$path]) ? $summed[$path] + $value : $value; });
Оба дадут
Array ( [/path/file.jpg] => 4 [/path/file2.bmp] => 3 [/file3.gif] => 5 )