关于php:如何对多维数组中的所有列值求和?

How to sum all column values in multi-dimensional array?

如何通过关联键添加所有列值? 请注意,键集是动态的。

输入数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Array
(
    [0] =;gt; Array
        (
            [gozhi] =;gt; 2
            [uzorong] =;gt; 1
            [ngangla] =;gt; 4
            [langthel] =;gt; 5
        )

    [1] =;gt; Array
        (
            [gozhi] =;gt; 5
            [uzorong] =;gt; 0
            [ngangla] =;gt; 3
            [langthel] =;gt; 2
        )

    [2] =;gt; Array
        (
            [gozhi] =;gt; 3
            [uzorong] =;gt; 0
            [ngangla] =;gt; 1
            [langthel] =;gt; 3
        )
)

所需结果:

1
2
3
4
5
6
7
Array
(
    [gozhi] =;gt; 10
    [uzorong] =;gt; 1
    [ngangla] =;gt; 8
    [langthel] =;gt; 10
)


您可以使用array_walk_recursive()来获得问题的一般解决方案(每个内部数组可能具有唯一键的解决方案)。

1
2
3
4
5
$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()函数来获得所需的确切键的结果,例如:

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

指定键的array_column()示例

如果要使用相同的键获取所有内部数组的总和(已发布所需的结果),则可以执行以下操作(请记住,第一个内部数组必须具有与其他内部数组相同的结构) ):

1
2
3
4
5
6
7
$final = array_shift($input);

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

unset($value);

如果所有内部数组都具有相同的键,则使用array_column()的示例

如果要使用array_column()的一般情况解决方案,那么首先可以考虑获取所有唯一键,然后获取每个键的总和:

1
2
3
4
5
6
7
8
9
$final = array();

foreach($input as $value)
    $final = array_merge($final, $value);

foreach($final as $key =;gt; ;$value)
    $value = array_sum(array_column($input, $key));

unset($value);

一般情况下array_column()的示例


1
2
3
4
5
6
7
8
9
$sumArray = array();

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

print_r($sumArray);


这是与其他两个类似的解决方案:

1
2
3
4
5
6
$acc = array_shift($arr);
foreach ($arr as $val) {
    foreach ($val as $key => $val) {
        $acc[$key] += $val;
    }
}

但这并不需要检查阵列键是否已经存在,也不会发出通知。


也可以使用array_map完成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$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
2
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));


1
2
3
4
5
6
7
8
9
10
11
12
$newarr=array();
foreach($arrs as $value)
{
  foreach($value as $key=>$secondValue)
   {
       if(!isset($newarr[$key]))
        {
           $newarr[$key]=0;
        }
       $newarr[$key]+=$secondValue;
   }
}


另一个版本,下面有一些好处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$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,Graviton和Chris J的最佳答案与以下目标结合在一起,以便可以在我的应用程序中使用它:

a)在循环外部初始化"求和"数组键(Gumbo)。应该对非常大的阵列的性能有所帮助(尚未测试!)。消除通知。

b)主要逻辑易于理解,而无需触及手册。 (Graviton,Chris J)。

c)解决更普遍的问题,即使用相同的键将任意两个数组的值相加,并减少对子数组结构的依赖。

与Gumbo解决方案不同,您可以在值不在子数组中的情况下重用此方法。在下面的示例中,想像$arr1$arr2并不是硬编码的,而是在循环内调用函数的结果而返回的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$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完成:

1
2
3
4
5
6
7
8
9
10
11
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'));

不像以前的解决方案那样可读,但是可以工作:)


这是一个版本,其中两个数组的数组键可能不相同,但是您希望它们都在最终数组中。

1
2
3
4
5
6
7
8
9
10
function array_add_by_key( $array1, $array2 ) {
    foreach ( $array2 as $k =;gt; $a ) {
        if ( array_key_exists( $k, $array1 ) ) {
            $array1[$k] += $a;
        } else {
            $array1[$k] = $a;
        }
    }
    return $array1;
}

我们需要首先检查数组键是否确实存在。

码:

1
2
3
4
5
6
7
8
9
10
11
12
13
$sum = array();
foreach ($array as $key =;gt; $sub_array) {
    foreach ($sub_array as $sub_key =;gt; $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);

具有阵列键验证的输出:

1
2
3
4
5
6
7
Array
(
    [gozhi] =;gt; 10
    [uzorong] =;gt; 1
    [ngangla] =;gt; 8
    [langthel] =;gt; 10
)

没有阵列键验证的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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] =;gt; 10
    [uzorong] =;gt; 1
    [ngangla] =;gt; 8
    [langthel] =;gt; 10
)

尽管它打印输出,但这是一个不好的做法。始终先检查密钥是否存在。


对于那些登陆这里并正在寻找一种解决方案,该解决方案可以合并N个数组并求和N个数组中找到的相同键的值,我编写了此函数,该函数也可以递归工作。 (请参阅:https://gist.github.com/Nickology/f700e319cbafab5eaedc)

例:

1
2
3
4
5
$a = array("A" =;gt;"bob","sum" =;gt; 10,"C" =;gt; array("x","y","z" =;gt; 50) );
$b = array("A" =;gt;"max","sum" =;gt; 12,"C" =;gt; array("x","y","z" =;gt; 45) );
$c = array("A" =;gt;"tom","sum" =;gt;  8,"C" =;gt; array("x","y","z" =;gt; 50,"w" =;gt; 1) );

print_r(array_merge_recursive_numeric($a,$b,$c));

将导致:

1
2
3
4
5
6
7
8
9
10
11
12
13
Array
(
    [A] =;gt; tom
    [sum] =;gt; 30
    [C] =;gt; Array
        (
            [0] =;gt; x
            [1] =;gt; y
            [z] =;gt; 145
            [w] =;gt; 1
        )

)

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
;lt;?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 ;lt;[email protected];gt;
 * @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 =;gt; $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 =;gt; $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 =;gt; $value) {
            if (!isset($final[$key])) {
                $final[$key] = $value;
            }
        }

    }

    return $final;

}

?;gt;


遍历数组的每个项目,并将值加和到先前的值(如果存在),如果不只是分配值的话。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
;lt;?php
$array =
[
    [
        'a'=;gt;1,
        'b'=;gt;1,
        'c'=;gt;1,
    ],
    [
        'a'=;gt;2,
        'b'=;gt;2,
    ],
    [
        'a'=;gt;3,
        'd'=;gt;3,
    ]
];

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

    return $carry;
}, []);

print_r($result);

输出:

1
2
3
4
5
6
7
Array
(
    [a] =;gt; 6
    [b] =;gt; 3
    [c] =;gt; 1
    [d] =;gt; 3
)

在这里,您可以了解我通常如何进行此类操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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=;gt;$subArray) {

   // Each value is an array, we loop through it
   foreach ($subArray as $id=;gt;$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项目中效果很好

1
2
3
4
5
6
7
8
9
10
print_r($Array); // your original array

$_SUM = [];

// count($Array[0]) =;gt; if the number of keys are equall in all arrays then do a count of index 0 etc.
for ($i=0; $i ;lt; 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
2
3
$c = array_map(function () {
      return array_sum(func_get_args());
     },$a, $b);

最后:

1
print_r($c);


1
2
3
4
5
6
7
8
9
$sumArray = array();
foreach ($myArray as $k =;gt; $subArray) {
    foreach ($subArray as $id =;gt; $value) {
        if (!isset($sumArray[$id])) {
            $sumArray[$id] = 0;
        }
        $sumArray[$id]+=$value;
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$sumArray = array();

foreach ($myArray as $k=;gt;$subArray) {
  foreach ($subArray as $id=;gt;$value) {
    if(!isset($sumArray[$id])){
     $sumArray[$id] =$value;
    }else {
     $sumArray[$id]+=$value;
    }
  }
}

print_r($sumArray);

`


例如,您可以从下面的结果中选择所有字段。

我正在从数组中选择"平衡"并保存到变量

1
$kii =   $user-;gt;pluck('balance');

然后在下一行,您可以像这样总结:

1
$sum =  $kii-;gt;sum();

希望能帮助到你。