Как суммировать все значения столбцов в многомерном массиве?
Как я могу добавить все столбчатые значения по ассоциативному ключу? Обратите внимание, что [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 answers
$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);
Пример с array_column()
для общего случая
Вот решение, аналогичное двум другим:
$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) Инициализируйте ключи массива "сумма" вне цикла (Гамбо). Должно помочь с производительностью на очень больших массивах (еще не протестировано!). Устраняет уведомления.
Б) Основную логику легко понять, не обращаясь к руководствам. (Гравитон, Крис Джей).
В) Решить более общая проблема добавления значений любых двух массивов с одинаковыми ключами и делает его менее зависимым от структуры подмассива.
В отличие от решения 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'));
Не так читаемо, как предыдущие решения, но это работает:)
Используйте этот фрагмент:
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Вот версия, в которой ключи массива могут не совпадать для обоих массивов, но вы хотите, чтобы все они были в конечном массиве.
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 <[email protected]>
* @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
$sumArray = array();
foreach ($myArray as $k => $subArray) {
foreach ($subArray as $id => $value) {
if (!isset($sumArray[$id])) {
$sumArray[$id] = 0;
}
$sumArray[$id]+=$value;
}
}
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
if(!isset($sumArray[$id])){
$sumArray[$id] =$value;
}else {
$sumArray[$id]+=$value;
}
}
}
print_r($sumArray);
`