Bagaimana cara menjumlahkan semua nilai kolom dalam array multi-dimensi?


116

Bagaimana cara menambahkan semua nilai kolom dengan kunci asosiatif? Perhatikan bahwa kumpulan kunci bersifat dinamis.

Array masukan:

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

Hasil yang diinginkan:

Array
(
    [gozhi] => 10
    [uzorong] => 1
    [ngangla] => 8
    [langthel] => 10
)

Untuk situasi umum, dua array multidimensi tidak memiliki kunci yang persis sama. menggabungkan / jumlah array multi dimensi php
Kris Roofe

Jawaban:


92
$sumArray = array();

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

print_r($sumArray);

49
Itu akan memunculkan pemberitahuan untuk iterasi pertama karena kuncinya belum ada.
Gumbo

Jika ada n array?
Muhammad Usman

2
@RanaMuhammadUsman: Jika ada narray, gunakan solusi ini .
Amal Murali

2
array_reduce terdengar paling cantik bagi saya stackoverflow.com/questions/14195916/…
Bill'o

13
Untuk menghindari pemberitahuan, Anda bisa mengganti baris yang menetapkan nilai ke $ sumArray to: array_key_exists ($ id, $ sumArray)? $ sumArray [$ id] + = $ nilai: $ sumArray [$ id] = $ nilai;
Dave O'Brien

185

Anda dapat menggunakan array_walk_recursive()untuk mendapatkan solusi kasus umum untuk masalah Anda ( solusi ketika setiap array dalam mungkin memiliki kunci unik ).

$final = array();

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

Contoh dengan array_walk_recursive()untuk kasus umum

Juga, karena PHP 5.5 Anda dapat menggunakan array_column()fungsi untuk mencapai hasil yang Anda inginkan untuk tombol yang tepat , [gozhi]misalnya:

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

Contoh dengan array_column()untuk kunci yang ditentukan

Jika Anda ingin mendapatkan jumlah total dari semua array dalam dengan kunci yang sama ( hasil yang diinginkan yang telah Anda posting ), Anda dapat melakukan sesuatu seperti ini (perlu diingat bahwa array dalam pertama harus memiliki struktur yang sama dengan yang lain. ):

$final = array_shift($input);

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

unset($value);

Contoh dengan array_column()seandainya semua array dalam memiliki kunci yang sama

Jika Anda ingin menggunakan solusi kasus umum array_column()maka pada awalnya Anda dapat mempertimbangkan untuk mendapatkan semua kunci unik, dan kemudian mendapatkan jumlah untuk setiap kunci:

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

Contoh dengan array_column()untuk kasus umum


31

Gunakan cuplikan ini:

$key = 'gozhi';
$sum = array_sum(array_column($array,$key));

Saya telah mengedit pertanyaan untuk mengklarifikasi bahwa solusi ini agak kurang matang dalam hal memberikan hasil yang diinginkan OP. Meskipun demikian, jika Anda ingin memperluas jawaban Anda, kemungkinan besar itu akan menjadi duplikat dari jawaban yang diposting sebelumnya.
mickmackusa

28

Berikut adalah solusi yang mirip dengan dua solusi lainnya:

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

Tetapi ini tidak perlu memeriksa apakah kunci array sudah ada dan tidak juga memberikan pemberitahuan.


+1 solusi yang sangat cerdas untuk struktur array khusus ini. Sayang sekali itu tidak berfungsi dalam kasus array yang lebih umum yang semuanya terstruktur seperti hasil akhir.
Todd Chaffee

22

Itu juga bisa dilakukan dengan menggunakan 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
Sempurna untuk n nomor larik
Dushyant Joshi

1
Bagaimana Anda akan mengubah ini untuk N nomor larik?
Pathros

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

3
Perhatikan bahwa ini akan memberi Anda pemberitahuan PHP (indeks tidak ditentukan) setiap kali Anda mengakses $ newarr [$ key] di sisi kanan tugas Anda, ketika nilai-nilai tersebut belum ada.
Anti Veeranna

Saya rasa saya menambahkan cek untuk menginisialisasi $ newarr [$ key]
Graviton

4
TOLONG tinggalkan komentar jika Anda menolak seseorang ... Tidak ada cara untuk meningkatkan solusi jika Anda tidak meninggalkan komentar.
Todd Chaffee

@Graviton Saya tidak downvote, tetapi saya akan menyatakan bahwa setiap jawaban StackOverflow harus menyertakan beberapa penjelasan tentang cara kerja solusi dan / atau mengapa itu disarankan. Ingat setiap halaman di situs / jaringan ini adalah sumber daya pendidikan bagi ribuan pengembang dengan berbagai keterampilan / pengetahuan. (Jika saya menurunkan suara setiap kali saya menemukan jawaban hanya-kode, saya akan kehabisan poin perwakilan.)
mickmackusa

5

Versi lain, dengan beberapa keunggulan di bawah.

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

}

Saya ingin menggabungkan yang terbaik dari jawaban Gumbo, Graviton, dan Chris J dengan tujuan berikut sehingga saya dapat menggunakan ini di aplikasi saya:

a) Inisialisasi kunci array 'sum' di luar loop (Gumbo). Harus membantu dengan kinerja pada array yang sangat besar (belum diuji!). Menghilangkan pemberitahuan.

b) Logika utama mudah dipahami tanpa harus membaca manual. (Graviton, Chris J).

c) Selesaikan masalah yang lebih umum untuk menambahkan nilai dari dua larik mana pun dengan kunci yang sama dan membuatnya kurang bergantung pada struktur sub larik.

Tidak seperti solusi Gumbo, Anda dapat menggunakan kembali ini jika nilainya tidak berada dalam sub larik. Bayangkan dalam contoh di bawah ini $arr1dan $arr2tidak dikodekan dengan keras, tetapi dikembalikan sebagai hasil dari memanggil fungsi di dalam loop.

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

4

Itu juga bisa dilakukan dengan menggunakan 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'));

Tidak begitu dapat dibaca seperti solusi sebelumnya tetapi berfungsi :)


3

Berikut adalah versi di mana kunci array mungkin tidak sama untuk kedua array, tetapi Anda ingin semuanya ada di array terakhir.

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

3

Kita perlu memeriksa dulu apakah kunci array memang ada.

KODE:

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

OUTPUT Dengan Validasi Kunci Array:

Array
(
    [gozhi] => 10
    [uzorong] => 1
    [ngangla] => 8
    [langthel] => 10
)

OUTPUT Tanpa Validasi Kunci Array:

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
)

Ini adalah praktik yang buruk meskipun hasilnya dicetak. Selalu periksa dulu jika ada kunci.


1

Bagi mereka yang mendarat di sini dan mencari solusi yang menggabungkan array N DAN juga menjumlahkan nilai kunci identik yang ditemukan di array N, saya telah menulis fungsi ini yang bekerja secara rekursif juga. (Lihat: https://gist.github.com/Nickology/f700e319cbafab5eaedc )

Contoh:

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

Akan menghasilkan:

Array
(
    [A] => tom
    [sum] => 30
    [C] => Array
        (
            [0] => x
            [1] => y
            [z] => 145
            [w] => 1
        )

)

Berikut kodenya:

<?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;

}

?>

1

Pergi melalui setiap item dari array dan jumlah nilai ke nilai sebelumnya jika ada, jika tidak hanya menetapkan nilainya.

<?php
$array = 
[
    [
        'a'=>1,
        'b'=>1,
        'c'=>1,
    ],
    [
        'a'=>2,
        'b'=>2,
    ],
    [
        'a'=>3,
        'd'=>3,
    ]
];

$result = array_reduce($array, function($carry, $item) {
    foreach($item as $k => $v)
        $carry[$k] = $v + ($carry[$k] ?? 0);

    return $carry;
}, []);

print_r($result);

Keluaran:

Array
(
    [a] => 6
    [b] => 3
    [c] => 1
    [d] => 3
)

Atau cukup putar melalui setiap sub larik, dan kelompokkan nilai untuk setiap kolom. Akhirnya menjumlahkannya:

foreach($array as $subarray)
    foreach($subarray as $key => $value)
        $grouped[$key][] = $value;

$sums = array_map('array_sum', $grouped);

0

Di sini Anda mengetahui bagaimana saya biasanya melakukan operasi semacam ini.

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

Tolong bisakah Anda memberikan penjelasan tentang kode ini, dan mengapa itu menjawab pertanyaan? Ini akan lebih membantu daripada hanya membuang blok kode tanpa penjelasan apa pun.
trincot

tentu saja!! Maaf, saya orang Spanyol dan bagi saya, menjelaskan kode adalah hal tersulit ketika saya menjawab pertanyaan! Terima kasih atas saran Anda @trincot
Luis González

0

Anda dapat mencoba ini:

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

dan akhirnya:

print_r($c);

1
Apa sebenarnya yang Anda gunakan untuk $adan $bkapan Anda menelepon array_map()? Harap perbaiki jawaban hanya kode ini.
mickmackusa

0

ini berfungsi dengan baik pada proyek laravel saya

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

Meskipun ini mungkin berhasil untuk proyek Laravel Anda, ini bukan solusi yang baik / bisa diterapkan untuk pertanyaan INI.
mickmackusa

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

Ini adalah duplikat dari jawaban dari BANYAK tahun sebelumnya. stackoverflow.com/a/1496697/2943403 Harap baca semua jawaban yang ada sebelum Anda memposting jawaban Anda sendiri sehingga tidak ada redundansi pada halaman yang sama.
mickmackusa

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

`

Harap tinjau Bagaimana cara menulis jawaban yang baik . Jawaban kode saja tidak disarankan karena tidak menjelaskan cara menyelesaikan masalah dalam pertanyaan. Anda harus memperbarui jawaban Anda untuk menjelaskan apa yang dilakukannya dan bagaimana meningkatkannya pada banyak jawaban positif yang sudah dimiliki oleh pertanyaan berusia 8 tahun ini.
FluffyKitten

Pada dasarnya duplikat dari jawaban sebelumnya: stackoverflow.com/a/20532196/2943403
mickmackusa

-2

Misalnya, Anda dapat mengambil semua bidang dari hasil seperti ini di bawah.

Saya memilih 'keseimbangan' dari array dan menyimpan ke variabel

$kii =   $user->pluck('balance');

lalu di baris selanjutnya kamu bisa menjumlahkan seperti ini:

$sum =  $kii->sum(); 

Semoga membantu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.