Как суммировать все значения столбцов в многомерном массиве?
как я могу добавить все столбчатые значения ассоциативным ключом? Обратите внимание, что [gozhi]
ключ динамический.
входной массив :
Array
(
[0] => Array
(
[gozhi] => 2
[uzorong] => 1
[ngangla] => 4
[langthel] => 5
)
[1] => Array
(
[gozhi] => 5
[uzorong] => 0
[ngangla] => 3
[langthel] => 2
)
[2] => Array
(
[gozhi] => 3
[uzorong] => 0
[ngangla] => 1
[langthel] => 3
)
)
желаемый результат :
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
16 ответов:
$sumArray = array(); foreach ($myArray as $k=>$subArray) { foreach ($subArray as $id=>$value) { $sumArray[$id]+=$value; } } print_r($sumArray);
можно использовать
array_walk_recursive()
чтобы получить общее решение для вашей проблемы (когда каждый внутренний массив может иметь уникальные ключи).$final = array(); array_walk_recursive($input, function($item, $key) use (&$final){ $final[$key] = isset($final[$key]) ? $item + $final[$key] : $item; });
пример
array_walk_recursive()
для общего случаякроме того, поскольку PHP 5.5 можно использовать
array_column()
функция для достижения желаемого результата для точный ключ,[gozhi]
, например :array_sum(array_column($input, 'gozhi'));
пример
array_column()
для указанного ключаесли вы хотите получить общую сумму всех внутренних массивы с одинаковыми ключами (желаемый результат, который вы опубликовали), вы можете сделать что-то подобное (имея в виду, что первый внутренний массив должен иметь ту же структуру, что и остальные) :
$final = array_shift($input); foreach ($final as $key => &$value){ $value += array_sum(array_column($input, $key)); } unset($value);
пример
array_column()
в случае, если все внутренние массивы имеют одинаковые клавишиесли вы хотите решение общего случая с помощью
array_column()
затем сначала вы можете рассмотреть, чтобы получить все уникальные ключи , а затем вам сумму для каждого ключа :$final = array(); foreach($input as $value) $final = array_merge($final, $value); foreach($final as $key => &$value) $value = array_sum(array_column($input, $key)); unset($value);
вот решение, похожее на два других:
$acc = array_shift($arr); foreach ($arr as $val) { foreach ($val as $key => $val) { $acc[$key] += $val; } }
но это не нужно, чтобы проверить, если ключи массива уже существуют и не бросает уведомления ни.
Это также можно сделать с помощью
array_map
:$rArray = array( 0 => array( 'gozhi' => 2, 'uzorong' => 1, 'ngangla' => 4, 'langthel' => 5 ), 1 => array( 'gozhi' => 5, 'uzorong' => 0, 'ngangla' => 3, 'langthel' => 2 ), 2 => array( 'gozhi' => 3, 'uzorong' => 0, 'ngangla' => 1, 'langthel' => 3 ), ); $sumResult = call_user_func_array('array_map', array_merge(['sum'], $rArray)); function sum() { return array_sum(func_get_args()); }
$newarr=array(); foreach($arrs as $value) { foreach($value as $key=>$secondValue) { if(!isset($newarr[$key])) { $newarr[$key]=0; } $newarr[$key]+=$secondValue; } }
другая версия, с некоторыми преимуществами ниже.
$sum = ArrayHelper::copyKeys($arr[0]); foreach ($arr as $item) { ArrayHelper::addArrays($sum, $item); } class ArrayHelper { public function addArrays(Array &$to, Array $from) { foreach ($from as $key=>$value) { $to[$key] += $value; } } public function copyKeys(Array $from, $init=0) { return array_fill_keys(array_keys($from), $init); } }
Я хотел объединить лучшее из ответа Гамбо, гравитона и Криса Дж со следующими целями, чтобы я мог использовать это в своем приложении:
A) инициализируйте ключи массива " sum " вне цикла (Gumbo). Должно помочь с производительностью на очень больших массивах (еще не протестировано!). Устраняет уведомления.
b) основная логика легко понять, не задев руководства. (Гравитон, Крис Дж.)
c) решите более общую задачу добавления значений любых двух массивов с одинаковыми ключами и сделайте ее менее зависимой от структуры суб-массива.
В отличие от решения Gumbo, вы можете использовать его в тех случаях, когда значения не находятся в суб-массивах. Представить в приведенном ниже примере, что
$arr1
и$arr2
не жестко закодированы, но возвращаются в результате вызова функции внутри цикла.$arr1 = array( 'gozhi' => 2, 'uzorong' => 1, 'ngangla' => 4, 'langthel' => 5 ); $arr2 = array( 'gozhi' => 5, 'uzorong' => 0, 'ngangla' => 3, 'langthel' => 2 ); $sum = ArrayHelper::copyKeys($arr1); ArrayHelper::addArrays($sum, $arr1); ArrayHelper::addArrays($sum, $arr2);
Это также можно сделать с помощью
array_walk
:function array_sum_values(array $input, $key) { $sum = 0; array_walk($input, function($item, $index, $params) { if (!empty($item[$params[1]])) $params[0] += $item[$params[1]]; }, array(&$sum, $key) ); return $sum; } var_dump(array_sum_values($arr, 'gozhi'));
не так читаем, как предыдущие решения, но это работает:)
вот версия, где ключи массива не могут быть одинаковыми для обоих массивов, но вы хотите, чтобы все они были там в конечном массиве.
function array_add_by_key( $array1, $array2 ) { foreach ( $array2 as $k => $a ) { if ( array_key_exists( $k, $array1 ) ) { $array1[$k] += $a; } else { $array1[$k] = $a; } } return $array1; }
нам нужно сначала проверить, существует ли ключ массива.
код:
$sum = array(); foreach ($array as $key => $sub_array) { foreach ($sub_array as $sub_key => $value) { //If array key doesn't exists then create and initize first before we add a value. //Without this we will have an Undefined index error. if( ! array_key_exists($sub_key, $sum)) $sum[$sub_key] = 0; //Add Value $sum[$sub_key]+=$value; } } print_r($sum);
вывод с проверкой ключа массива:
Array ( [gozhi] => 10 [uzorong] => 1 [ngangla] => 8 [langthel] => 10 )
вывод без проверки ключа массива:
Notice: Undefined index: gozhi in F:\web\index.php on line 37 Notice: Undefined index: uzorong in F:\web\index.php on line 37 Notice: Undefined index: ngangla in F:\web\index.php on line 37 Notice: Undefined index: langthel in F:\web\index.php on line 37 Array ( [gozhi] => 10 [uzorong] => 1 [ngangla] => 8 [langthel] => 10 )
Это плохая практика, хотя он печатает выходные. Всегда проверяйте сначала, существует ли ключ.
Вы можете попробовать это:
$c = array_map(function () { return array_sum(func_get_args()); },$a, $b);
и наконец:
print_r($c);
для тех, кто приземлился здесь и ищет решение, которое сливается N массивов а также суммирует значения идентичных ключей, найденных в N массивах, я написал эту функцию, которая также работает рекурсивно. (См.: https://gist.github.com/Nickology/f700e319cbafab5eaedc)
пример:
$a = array( "A" => "bob", "sum" => 10, "C" => array("x","y","z" => 50) ); $b = array( "A" => "max", "sum" => 12, "C" => array("x","y","z" => 45) ); $c = array( "A" => "tom", "sum" => 8, "C" => array("x","y","z" => 50, "w" => 1) ); print_r(array_merge_recursive_numeric($a,$b,$c));
в результате:
Array ( [A] => tom [sum] => 30 [C] => Array ( [0] => x [1] => y [z] => 145 [w] => 1 ) )
вот код:
<?php /** * array_merge_recursive_numeric function. Merges N arrays into one array AND sums the values of identical keys. * WARNING: If keys have values of different types, the latter values replace the previous ones. * * Source: https://gist.github.com/Nickology/f700e319cbafab5eaedc * @params N arrays (all parameters must be arrays) * @author Nick Jouannem <nick@nickology.com> * @access public * @return void */ function array_merge_recursive_numeric() { // Gather all arrays $arrays = func_get_args(); // If there's only one array, it's already merged if (count($arrays)==1) { return $arrays[0]; } // Remove any items in $arrays that are NOT arrays foreach($arrays as $key => $array) { if (!is_array($array)) { unset($arrays[$key]); } } // We start by setting the first array as our final array. // We will merge all other arrays with this one. $final = array_shift($arrays); foreach($arrays as $b) { foreach($final as $key => $value) { // If $key does not exist in $b, then it is unique and can be safely merged if (!isset($b[$key])) { $final[$key] = $value; } else { // If $key is present in $b, then we need to merge and sum numeric values in both if ( is_numeric($value) && is_numeric($b[$key]) ) { // If both values for these keys are numeric, we sum them $final[$key] = $value + $b[$key]; } else if (is_array($value) && is_array($b[$key])) { // If both values are arrays, we recursively call ourself $final[$key] = array_merge_recursive_numeric($value, $b[$key]); } else { // If both keys exist but differ in type, then we cannot merge them. // In this scenario, we will $b's value for $key is used $final[$key] = $b[$key]; } } } // Finally, we need to merge any keys that exist only in $b foreach($b as $key => $value) { if (!isset($final[$key])) { $final[$key] = $value; } } } return $final; } ?>
здесь у вас есть, как я обычно делаю такого рода операции.
// We declare an empty array in wich we will store the results $sumArray = array(); // We loop through all the key-value pairs in $myArray foreach ($myArray as $k=>$subArray) { // Each value is an array, we loop through it foreach ($subArray as $id=>$value) { // If $sumArray has not $id as key we initialize it to zero if(!isset($sumArray[$id])){ $sumArray[$id] = 0; } // If the array already has a key named $id, we increment its value $sumArray[$id]+=$value; } } print_r($sumArray);
это отлично работает на моем проекте laravel
print_r($Array); // your original array $_SUM = []; // count($Array[0]) => if the number of keys are equall in all arrays then do a count of index 0 etc. for ($i=0; $i < count($Array[0]); $i++) { $_SUM[] = $Array[0][$i] + $Array[1][$i]; // do a for loop on the count } print_r($_SUM); // get a sumed up array