如何总结同一个键的数组的值?
我怎样才能添加键[gozhi]
所有值? 请注意, [gozhi]
键是dynamic的 。
input数组:
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 )
$sumArray = array(); foreach ($myArray as $k=>$subArray) { foreach ($subArray as $id=>$value) { $sumArray[$id]+=$value; } } print_r($sumArray);
你可以使用array_walk_recursive()
为你的问题得到一个通用的解决scheme( 当每个内部数组可能有唯一的键 )。
$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()
函数来实现所需的结果[gozhi]
,例如:
array_sum(array_column($input, 'gozhi'));
array_column()
为指定键的示例
如果你想得到所有内部数组的总和(相同的键),你可以做这样的事情(要记住,第一个内部数组必须具有与其他结构相同的结构 ):
$final = array_shift($input); foreach ($final as $key => &$value){ $value += array_sum(array_column($input, $key)); } unset($value);
如果所有内部数组具有相同的键,则使用array_column()
的示例
如果你想使用array_column()
的一般情况下的解决scheme,那么首先你可以考虑获得所有的唯一键,然后得到每个键的总和:
$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);
一般情况下array_column()
的例子
这是一个类似于另外两个的解决scheme:
$acc = array_shift($arr); foreach ($arr as $val) { foreach ($val as $key => $val) { $acc[$key] += $val; } }
但是这不需要检查数组键是否已经存在,也不会抛出通知。
它也可以使用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()); }
$newarr=array(); foreach($arrs as $value) { foreach($value as $key=>$secondValue) { if(!isset($newarr[$key])) { $newarr[$key]=0; } $newarr[$key]+=$secondValue; } }
另一个版本,下面有一些好处。
$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)初始化'sum'数组键。 应该有助于在非常大的数组上进行性能testing(尚未testing!)。 消除通知。
b)主要逻辑很容易理解,而不会碰到手册。 (Graviton,Chris J)。
c)解决更一般的问题,即使用相同的键添加任何两个数组的值,并使其对子数组结构的依赖性降低。
与Gumbo的解决scheme不同,如果值不在子数组中,则可以重新使用它。 想象一下,在下面的例子中, $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);
它也可以使用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'));
像以前的解决scheme不太可读,但它的工作:)
这里有一个版本,其中的数组键可能不是相同的两个数组,但你希望他们都在最后一个数组中。
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; }
你可以试试这个:
$c = array_map(function () { return array_sum(func_get_args()); },$a, $b);
最后:
print_r($c);
对于那些降落在这里,正在寻找合并N个数组的解决scheme,并且还总结了在N个数组中find的相同键的值,我写了这个recursion地工作的函数。 (见: 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 <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; } ?>
添加multidimensional array与错误validation。
$arrOne = array( 'k1'=>'1', 'k2'=>'1', 'k3'=>'1', 'k5'=>array( 'osk1'=>'1', 'osk2'=>'1', 'osk3'=>array( 'osk33'=>array( ':P' ), ) ), 'k7'=>'', '0'=>'12', ); $arrTwo = array( 'k1'=>'1', 'k2'=>'1', 'k4'=>'1', 'k5'=>array( 'osk1'=>'1', 'osk3'=>array( 'osk33'=>'1' ), ), 'k6'=>array( 'osk3'=>array( 'osk33'=>'1' ), ), 'k7'=>1, 'k8'=>array(), 'k9'=>'0', '2'=>'123', ); echo "<pre>"; print_r(addArrays($arrOne,$arrTwo)); echo "</pre>"; function addArrays($arrOne, $arrTwo){ if(empty($arrOne)){ $arrOne = array(); } if(empty($arrTwo)){ $arrTwo = array(); } $arrFinal = $arrOne; foreach ($arrTwo as $key=>$value) { if(!isset($arrFinal[$key])){ //If key not exist in array one, define data type same as array two. if(is_array($value)){ $arrFinal[$key] = array(); } else if(is_string($value)){ $arrFinal[$key] = 0; } else{ $arrFinal[$key] = NULL; } } if(empty($arrFinal[$key]) && !empty($value)){ $arrFinal[$key] = $value; } else if(gettype($arrFinal[$key]) != gettype($value)){ continue; } else if(!is_array($value) && !is_object($value)){ $arrFinal[$key] += $value; } else if(is_array($value) && !is_object($value)){ $arrFinal[$key] = addArrays($arrFinal[$key], $value); } else if(is_string($value) || is_int($value) || is_float($value)){ $arrFinal[$key] += $value; } else{ $arrFinal[$key] = $value; } } return $arrFinal; }
在这里,你有我通常做这种操作。
// 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);
$sumArray = array(); foreach ($myArray as $k => $subArray) { foreach ($subArray as $id => $value) { if (!isset($sumArray[$id])) { $sumArray[$id] = 0; } $sumArray[$id]+=$value; } }
$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); `