2009-09-30 3 views
82

Как добавить все значения ключа [gozhi]? Отметьте, что [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 
) 
+0

Для обычной ситуации две многомерные матрицы не имеют точно таких же ключей. [merge/sum multi dimentional array php] (https://stackoverflow.com/q/44607229/6521116) –

ответ

74
$sumArray = array(); 

foreach ($myArray as $k=>$subArray) { 
    foreach ($subArray as $id=>$value) { 
    $sumArray[$id]+=$value; 
    } 
} 

print_r($sumArray); 
+36

Это будет выдавать уведомления для первой итерации, поскольку ключи еще не существуют. – Gumbo

+0

Если есть n массивов? –

+2

@RanaMuhammadUsman: Если есть 'n' массивы, используйте [это решение] (http://stackoverflow.com/a/9938193/1438393). –

11
$newarr=array(); 
foreach($arrs as $value) 
{ 
    foreach($value as $key=>$secondValue) 
    { 
     if(!isset($newarr[$key])) 
     { 
      $newarr[$key]=0; 
     } 
     $newarr[$key]+=$secondValue; 
    } 
} 
+2

Обратите внимание, что это даст вам уведомления PHP (неопределенный индекс) при каждом доступе к $ newarr [$ key] справа стороне вашего задания, когда такие значения еще не существуют. –

+0

Думаю, я добавляю чек для инициализации $ newarr [$ key] – Graviton

+4

Что? Я проголосовал? По какой причине? – Graviton

25

Вот решение аналогично двум другим:

$acc = array_shift($arr); 
foreach ($arr as $val) { 
    foreach ($val as $key => $val) { 
     $acc[$key] += $val; 
    } 
} 

Но это не нужно проверять, существуют ли ключи массива и не выдают уведомления.

+0

+1 очень умное решение для этой конкретной структуры массива. Слишком плохо, что он не работает в более общем случае массивов, все структурированные как конечный результат. –

5

Другая версия, с некоторыми преимуществами ниже.

$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); 
    } 

} 

Я хотел объединить лучшие Гамбо годов, Гравитон, и ответ Криса Джея со следующими целями, так что я мог бы использовать это в моем приложении:

а) Инициализировать ключи «сумма» массива за пределами цикл (Gumbo). Должна помогать с производительностью на очень больших массивах (еще не проверено!). Устраняет уведомления.

b) Основная логика проста в понимании, не затрагивая руководства. (Graviton, Chris J).

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); 
18

Она также может быть сделано с помощью 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()); 
} 
+1

Идеально подходит для n чисел массива –

+1

Как бы вы изменили это для N чисел массива? – Pathros

+0

@Pathros см. Обновленный ответ – sanmai

4

Она также может быть сделано с помощью 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')); 

Не так читаемый как и предыдущие решения, но это работает :)

3

Вот версия, где ключи массива могут быть не одинаковыми для обоих массивов, но y ou хочет, чтобы все они были в финальном массиве.

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; 
} 
120

Вы можете использовать array_walk_recursive(), чтобы получить общий случай решение вашей проблемы (тот, когда каждый внутренний массив может, возможно, имеет уникальные ключи).

$final = array(); 

array_walk_recursive($input, function($item, $key) use (&$final){ 
    $final[$key] = isset($final[$key]) ? $item + $final[$key] : $item; 
}); 

Example with array_walk_recursive() for the general case

Кроме того, поскольку PHP 5.5 вы можете использовать функцию array_column() для достижения желаемого результата для точного ключа, [gozhi], например:

array_sum(array_column($input, 'gozhi')); 

Example with array_column() for the specified key

Если вы хотите получить общую сумму всех внутренних массивов с теми же клавишами (желаемый результат, который вы опубликовали), вы можете сделать что-то вроде этого (, имея в виду, что первый внутренний массив должен иметь та же структура, как и другие):

$final = array_shift($input); 

foreach ($final as $key => &$value){ 
    $value += array_sum(array_column($input, $key)); 
}  

unset($value); 

Example with array_column() in case all inner arrays have the same keys

Если вы хотите общий случай решения с использованием 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); 

Example with array_column() for the general case

+6

Это лучший ответ. ☺ – Pathros

+2

Это должен быть выбранный ответ. –

+1

Это отличный трюк, спасибо, что поделились – trevorgk

0

Для тех, кто высадился здесь и ищет решение, которое сливает 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; 

} 

?> 
1

Вы можете попробовать это:

$c = array_map(function() { 
     return array_sum(func_get_args()); 
    },$a, $b); 

и, наконец:

print_r($c); 
0

Здесь у вас есть, как я обычно делаю такого рода операций.

// 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); 
+0

Пожалуйста, не могли бы вы дать объяснение этому коду и почему он отвечает на вопрос? Это будет более полезно, чем сбрасывать только блок кода без каких-либо объяснений. – trincot

+0

конечно !! Извините, я испанский и для меня, объясните, что код - самое трудное, когда я отвечаю на вопрос! Спасибо за совет @trincot –

0
$sumArray = array(); 
foreach ($myArray as $k => $subArray) { 
    foreach ($subArray as $id => $value) { 
     if (!isset($sumArray[$id])) { 
      $sumArray[$id] = 0; 
     } 
     $sumArray[$id]+=$value; 
    } 
} 
+3

Пожалуйста, добавьте пояснения к фрагменту кода. – styopdev

0
$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); 

` 
+0

Прочитайте [Как написать хороший ответ] (https://stackoverflow.com/help/how-to-answer). Кодовые ответы не приветствуются, потому что они не объясняют, как они разрешают проблему в вопросе. Вы должны обновить свой ответ, чтобы объяснить, что это делает, и как он улучшает многие ответы на этот 8-летний вопрос. – FluffyKitten

0

это прекрасно работает на моем 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 
1

Нам нужно проверить, если первый массив ключей существует.

КОД:

$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 
) 

Это плохая практика, хотя она печатает выходные данные. Всегда проверяйте, действительно ли ключ существует.

Смежные вопросы