Làm thế nào để tính tổng tất cả các giá trị cột trong mảng nhiều chiều?


116

Làm cách nào để thêm tất cả các giá trị cột bằng khóa kết hợp? Lưu ý rằng bộ khóa là động.

Mảng đầu vào:

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

Kết quả như ý:

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

Đối với một tình huống phổ biến, hai mảng nhiều thứ nguyên không có khóa chính xác giống nhau. merge / sum multi
dimentional

Câu trả lời:


92
$sumArray = array();

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

print_r($sumArray);

49
Điều đó sẽ đưa ra các thông báo cho lần lặp đầu tiên vì các khóa chưa tồn tại.
Gumbo 30/09/09

Nếu có n mảng?
Muhammad Usman

2
@RanaMuhammadUsman: Nếu có nmảng, hãy sử dụng giải pháp này .
Amal Murali

2
array_reduce nghe có vẻ đẹp nhất đối với tôi stackoverflow.com/questions/14195916/…
Bill'o

13
Để tránh các thông báo, bạn có thể thay thế dòng gán các giá trị cho $ sumArray thành: array_key_exists ($ id, $ sumArray)? $ sumArray [$ id] + = $ value: $ sumArray [$ id] = $ value;
Dave O'Brien

185

Bạn có thể sử dụng array_walk_recursive()để tìm giải pháp trường hợp chung cho vấn đề của mình (giải pháp khi mỗi mảng bên trong có thể có các khóa duy nhất ).

$final = array();

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

Ví dụ với array_walk_recursive()trường hợp chung

Ngoài ra, kể từ PHP 5,5 bạn có thể sử dụng array_column()chức năng để đạt được kết quả bạn muốn cho phím chính xác , [gozhi]ví dụ:

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

Ví dụ với array_column()khóa được chỉ định

Nếu bạn muốn nhận tổng cộng của tất cả các mảng bên trong có cùng các khóa ( kết quả mong muốn mà bạn đã đăng ), bạn có thể làm như sau ( lưu ý rằng mảng bên trong đầu tiên phải có cùng cấu trúc với các mảng khác ):

$final = array_shift($input);

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

unset($value);

Ví dụ với array_column()trường hợp tất cả các mảng bên trong có cùng khóa

Nếu bạn muốn một giải pháp trường hợp chung bằng cách sử dụng array_column()thì lúc đầu, bạn có thể cân nhắc lấy tất cả các khóa duy nhất, sau đó lấy tổng cho mỗi khóa:

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

Ví dụ với array_column()trường hợp chung


31

Sử dụng đoạn mã này:

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

Tôi đã chỉnh sửa câu hỏi để làm rõ rằng giải pháp này hơi thiếu nấu nướng về mặt cung cấp sản lượng mong muốn của OP. Điều đó nói lên rằng, nếu bạn mở rộng câu trả lời của mình, nó rất có thể trở thành một bản sao của các câu trả lời đã đăng trước đó.
mickmackusa

28

Đây là một giải pháp tương tự như hai giải pháp khác:

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

Nhưng điều này không cần phải kiểm tra xem các khóa mảng đã tồn tại hay chưa và cũng không đưa ra thông báo.


+1 giải pháp rất thông minh cho cấu trúc mảng cụ thể này. Thật tệ là nó không hoạt động trong trường hợp tổng quát hơn của các mảng có cấu trúc giống như kết quả cuối cùng.
Todd Chaffee

22

Nó cũng có thể được thực hiện bằng cách sử dụng 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
Hoàn hảo cho n số của mảng
Dushyant Joshi

1
Làm thế nào bạn sẽ thay đổi điều này cho N số của mảng?
Pathros

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

3
Lưu ý rằng điều này sẽ cung cấp cho bạn các thông báo PHP (chỉ mục không xác định) mỗi khi bạn truy cập $ newarr [$ key] ở phía bên phải của bài tập, khi các giá trị đó chưa tồn tại.
Anti Veeranna 30/09/09

Tôi nghĩ rằng tôi thêm một séc để khởi tạo $ newarr [$ key]
Graviton

4
VUI LÒNG để lại ý kiến ​​nếu bạn bỏ phiếu cho ai đó ... Không có cách nào để cải thiện giải pháp nếu bạn không để lại ý kiến.
Todd Chaffee

@Graviton Tôi không phản đối, nhưng tôi sẽ nói rằng mọi câu trả lời của StackOverflow nên bao gồm một số giải thích về cách giải pháp hoạt động và / hoặc tại sao nó được khuyến khích. Hãy nhớ rằng mỗi trang trên trang web / mạng này là tài nguyên giáo dục cho hàng nghìn hàng nghìn nhà phát triển với nhiều kỹ năng / kiến ​​thức. (Nếu tôi bỏ phiếu từ chối mỗi khi tôi tìm thấy câu trả lời chỉ có mã, tôi sẽ hết điểm đại diện.)
mickmackusa

5

Một phiên bản khác, với một số lợi ích bên dưới.

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

}

Tôi muốn kết hợp câu trả lời hay nhất của Gumbo, Graviton và Chris J với các mục tiêu sau để tôi có thể sử dụng câu trả lời này trong ứng dụng của mình:

a) Khởi tạo các khóa mảng 'tổng' bên ngoài vòng lặp (Gumbo). Sẽ giúp tăng hiệu suất trên các mảng rất lớn (chưa được thử nghiệm!). Loại bỏ thông báo.

b) Logic chính dễ hiểu mà không cần hướng dẫn sử dụng. (Graviton, Chris J).

c) Giải bài toán tổng quát hơn về việc cộng các giá trị của hai mảng bất kỳ có cùng khóa và làm cho nó ít phụ thuộc vào cấu trúc mảng con hơn.

Không giống như giải pháp của Gumbo, bạn có thể sử dụng lại điều này trong trường hợp các giá trị không nằm trong mảng con. Hãy tưởng tượng trong ví dụ bên dưới $arr1, $arr2nó không được mã hóa cứng, nhưng đang được trả về do kết quả của việc gọi một hàm bên trong một vòng lặp.

$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

Nó cũng có thể được thực hiện bằng cách sử dụng 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'));

Không dễ đọc như các giải pháp trước nhưng nó hoạt động :)


3

Đây là một phiên bản trong đó các khóa mảng có thể không giống nhau cho cả hai mảng, nhưng bạn muốn tất cả chúng đều ở đó trong mảng cuối cùng.

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

Trước tiên chúng ta cần kiểm tra xem khóa mảng có tồn tại hay không.

MÃ:

$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 Với Xác thực Khóa Mảng:

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

OUTPUT Không có Xác thực Khóa Mảng:

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
)

Đây là một thực tế không tốt mặc dù nó in ra đầu ra. Luôn kiểm tra trước nếu khóa tồn tại.


1

Đối với những người đã đến đây và đang tìm kiếm giải pháp hợp nhất N mảng VÀ cũng tính tổng các giá trị của các khóa giống hệt nhau được tìm thấy trong N mảng, tôi đã viết hàm này hoạt động đệ quy. (Xem: https://gist.github.com/Nickology/f700e319cbafab5eaedc )

Thí dụ:

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

Sẽ cho kết quả:

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

)

Đây là mã:

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

Đi qua từng mục của mảng và tính tổng các giá trị cho các giá trị trước đó nếu chúng tồn tại, nếu không chỉ cần gán giá trị.

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

Đầu ra:

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

Hoặc chỉ lặp qua từng mảng con và nhóm các giá trị cho từng cột. Cuối cùng tổng kết chúng:

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

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

0

Đây là cách tôi thường thực hiện loại hoạt động này.

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

Vui lòng bạn có thể giải thích về mã này và tại sao nó trả lời câu hỏi? Nó sẽ hữu ích hơn việc chỉ bán một khối mã mà không có bất kỳ lời giải thích nào.
trincot

tất nhiên!! Xin lỗi, tôi là người Tây Ban Nha và với tôi, giải thích mã là điều khó nhất khi tôi trả lời một câu hỏi! Cảm ơn bạn lời khuyên @trincot
Luis González

0

Bạn có thể thử điều này:

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

và cuối cùng:

print_r($c);

1
Chính xác thì bạn đang sử dụng để làm gì $a$bkhi nào bạn gọi array_map()? Vui lòng cải thiện câu trả lời chỉ có mã này.
mickmackusa

0

điều này hoạt động tốt trong dự án laravel của tôi

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

Mặc dù điều này có thể làm việc cho dự án Laravel của bạn, nhưng đây không phải là một giải pháp tốt / khả thi cho câu hỏi NÀY.
mickmackusa

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

Đây là một bản sao của một câu trả lời từ NHIỀU năm trước đó. stackoverflow.com/a/1496697/2943403 Vui lòng đọc tất cả các câu trả lời hiện có trước khi bạn đăng câu trả lời của riêng mình để không có câu trả lời dư thừa trên cùng một trang.
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);

`

Vui lòng xem lại Cách viết câu trả lời hay . Câu trả lời chỉ có mã không được khuyến khích vì chúng không giải thích cách chúng giải quyết vấn đề trong câu hỏi. Bạn nên cập nhật câu trả lời của mình để giải thích điều này có tác dụng gì và nó cải thiện như thế nào đối với nhiều câu trả lời được ủng hộ mà câu hỏi của cậu bé 8 tuổi này đã có.
FluffyKitten

Về cơ bản một bản sao của một câu trả lời trước đó: stackoverflow.com/a/20532196/2943403
mickmackusa

-2

Ví dụ: bạn có thể lấy tất cả các trường từ kết quả như sau.

Tôi đang chọn 'số dư' từ một mảng và lưu vào một biến

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

thì trên dòng tiếp theo, bạn có thể tính tổng như thế này:

$sum =  $kii->sum(); 

Hy vọng nó giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.