Çok boyutlu dizideki tüm sütun değerleri nasıl toplanır?


116

İlişkili anahtara göre tüm sütunlu değerleri nasıl ekleyebilirim? Anahtar kümelerinin dinamik olduğunu unutmayın.

Giriş dizisi:

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

İstenen sonuç:

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

Genel bir durum için, iki çok boyutlu dizi tam olarak aynı anahtarlara sahip değildir. birleştirme / toplama çok boyutlu dizi php
Kris Roofe

Yanıtlar:


92
$sumArray = array();

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

print_r($sumArray);

49
Bu, anahtarlar henüz mevcut olmadığından ilk yineleme için uyarılar atacaktır.
Gumbo

N dizi varsa?
Muhammed Usman

2
@RanaMuhammadUsman: nDiziler varsa , bu çözümü kullanın .
Amal Murali

2
array_reduce bana en güzel geliyor stackoverflow.com/questions/14195916/…
Bill'o

13
Uyarılardan kaçınmak için, değerleri $ sumArray'e atayan satırı değiştirebilirsiniz: array_key_exists ($ id, $ sumArray)? $ sumArray [$ id] + = $ değer: $ sumArray [$ id] = $ değer;
Dave O'Brien

185

array_walk_recursive()Probleminiz için genel bir çözüm elde etmek için kullanabilirsiniz ( her bir iç dizinin muhtemelen benzersiz anahtarları olabileceği durum ).

$final = array();

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

Örnek array_walk_recursive()genel durumu için

Ayrıca beri PHP 5.5 kullanabileceğiniz array_column()istediğiniz sonucu elde etmek için işlevini tam anahtarı için , [gozhi]örneğin:

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

array_column()Belirtilen anahtar için örnek

Aynı anahtarlarla ( gönderdiğiniz istenen sonuç) tüm iç dizilerin toplam toplamını elde etmek istiyorsanız, bunun gibi bir şey yapabilirsiniz ( ilk iç dizinin diğerleriyle aynı yapıya sahip olması gerektiğini unutmayın. ):

$final = array_shift($input);

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

unset($value);

array_column()Tüm iç dizilerin aynı anahtarlara sahip olması durumunda örnek

array_column()O zaman kullanarak genel bir çözüm istiyorsanız, önce tüm benzersiz anahtarları almayı ve ardından her anahtarın toplamını almayı düşünebilirsiniz:

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

Örnek array_column()genel durumu için


31

Bu pasajı kullanın:

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

Soruyu, bu çözümün OP'nin istenen çıktısını sağlama açısından biraz yetersiz pişirildiğini açıklığa kavuşturmak için düzenledim. Bununla birlikte, cevabınızı genişletirseniz, büyük olasılıkla daha önce gönderilen cevapların bir kopyası olur.
mickmackusa

28

İşte diğer ikisine benzer bir çözüm:

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

Ancak bunun, dizi anahtarlarının zaten var olup olmadığını kontrol etmesi gerekmez ve hiçbiri de uyarı vermez.


Bu özel dizi yapısı için +1 çok akıllı çözüm. Ne yazık ki, hepsi nihai sonuç gibi yapılandırılmış dizilerin daha genel durumunda çalışmıyor.
Todd Chaffee

22

Aşağıdakiler kullanılarak da yapılabilir 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 dizi dizisi için mükemmel
Dushyant Joshi

1
Bunu N dizi dizisi için nasıl değiştirirsiniz?
Pathros

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

3
Bunun, atamanızın sağ tarafındaki $ newarr [$ key] 'e her eriştiğinizde, bu tür değerler henüz mevcut olmadığında size PHP uyarıları (tanımsız dizin) vereceğini unutmayın.
Anti Veeranna

Sanırım $ newarr [$ key]
Graviton

4
Birini olumsuz oylarsanız LÜTFEN yorum bırakın ... Yorum bırakmazsanız çözümü iyileştirmenin bir yolu yoktur.
Todd Chaffee

@Graviton Olumsuz oy vermedim, ancak her StackOverflow yanıtının, çözümün nasıl çalıştığına ve / veya neden tavsiye edildiğine dair bazı açıklamalar içermesi gerektiğini belirteceğim. Bu sitedeki / ağdaki her sayfanın, çok çeşitli becerilere / bilgiye sahip binlerce geliştirici için bir eğitim kaynağı olduğunu unutmayın. (Her seferinde yalnızca kod içeren bir yanıt bulduğumda olumsuz oy kullanırsam, tekrar puanlarım biter.)
mickmackusa

5

Aşağıda bazı avantajları olan başka bir sürüm.

$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's, Graviton's ve Chris J'nin en iyi cevabını aşağıdaki hedeflerle birleştirmek istedim, böylece bunu uygulamamda kullanabilirim:

a) Döngünün dışındaki 'toplam' dizi anahtarlarını başlatın (Gumbo). Çok büyük dizilerde performansa yardımcı olmalıdır (henüz test edilmemiştir!). Bildirimleri ortadan kaldırır.

b) Kılavuzlara basmadan ana mantığı anlamak kolaydır. (Graviton, Chris J).

c) Herhangi iki dizinin değerlerini aynı anahtarlarla toplama gibi daha genel bir sorunu çözün ve alt dizi yapısına daha az bağımlı hale getirin.

Gumbo'nun çözümünden farklı olarak, değerlerin alt dizilerde olmadığı durumlarda bunu yeniden kullanabilirsiniz. Bu aşağıdaki örnekte düşünün $arr1ve $arr2kodlanmış değil, bir döngü içinde bir işlevinin çağrılması sonucunda döndürülen edilmektedir.

$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

Aşağıdakiler kullanılarak da yapılabilir 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'));

Önceki çözümler kadar okunabilir değil ama işe yarıyor :)


3

İşte dizi anahtarlarının her iki dizi için aynı olmayabileceği bir sürüm, ancak hepsinin son dizide olmasını istiyorsunuz.

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

Önce dizi anahtarının var olup olmadığını kontrol etmeliyiz.

KODU:

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

Dizi Anahtar Doğrulamalı ÇIKIŞ:

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

Dizi Anahtar Doğrulaması Olmadan ÇIKIŞ:

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
)

Çıktıyı yazdırmasına rağmen bu kötü bir uygulamadır. Her zaman önce anahtarın olup olmadığını kontrol edin.


1

Buraya inen ve N dizilerini birleştiren VE aynı zamanda N dizilerinde bulunan aynı anahtarların değerlerini toplayan bir çözüm arayanlar için , yinelemeli olarak da çalışan bu işlevi yazdım. (Bkz: https://gist.github.com/Nickology/f700e319cbafab5eaedc )

Misal:

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

Sonuçlanacak:

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

)

İşte kod:

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

Dizinin her bir öğesini gözden geçirin ve varsa değerleri önceki değerlere toplayın, yalnızca değeri atamak için değilse.

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

Çıktı:

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

Ya da her bir alt dizide döngü yapın ve her sütunun değerlerini gruplayın. Sonunda onları özetlemek:

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

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

0

Burada genellikle bu tür işlemleri nasıl yaptığımı görüyorsunuz.

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

Lütfen bu kodun bir açıklamasını ve soruyu neden cevapladığını söyler misiniz? Herhangi bir açıklama olmadan sadece bir kod bloğunu dökmekten daha yararlı olacaktır.
trincot

elbette!! Üzgünüm, İspanyolca'yım ve bana göre, bir soruyu yanıtladığımda kodun en zor şey olduğunu açıklayın! Tavsiyen için teşekkürler @trincot
Luis González

0

Bunu deneyebilirsiniz:

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

ve sonunda:

print_r($c);

1
Tam olarak ne için $ave $bne zaman array_map()arıyorsun? Lütfen bu yalnızca kod yanıtını geliştirin.
mickmackusa

0

bu, laravel projemde harika çalışıyor

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

Bu, Laravel projeniz için işe yarayabilir, ancak bu, BU soru için iyi / uygulanabilir bir çözüm değildir.
mickmackusa

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

Bu, BİRÇOK yıl öncesinden gelen bir yanıtın kopyasıdır. stackoverflow.com/a/1496697/2943403 Lütfen aynı sayfada fazlalık olmaması için kendi yanıtlarınızı göndermeden önce mevcut tüm yanıtları okuyun.
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);

`

Lütfen inceleyin Nasıl iyi bir cevap yazarım . Yalnızca kod yanıtları, sorudaki sorunu nasıl çözdüklerini açıklamadıkları için önerilmez. Cevabınızı, bunun ne yaptığını ve bu 8 yıllık sorunun halihazırda sahip olduğu pek çok yükseltilmiş cevapta nasıl geliştiğini açıklamak için güncellemelisiniz.
FluffyKitten

Temelde daha önceki bir cevabın kopyası: stackoverflow.com/a/20532196/2943403
mickmackusa

-2

Örneğin, aşağıdaki gibi bir sonuçtan tüm alanları çıkarabilirsiniz.

Bir diziden 'dengeyi' seçiyorum ve bir değişkene kaydediyorum

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

sonra bir sonraki satırda şu şekilde toplayabilirsiniz:

$sum =  $kii->sum(); 

Umarım yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.