Comment puis-je ajouter toutes les valeurs en colonnes par clé associative? Notez que[gozhi]
key est dynamic .
Tableau d'entrée:
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
)
)
Résultat désiré :
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);
Vous pouvez utiliser array_walk_recursive()
pour obtenir une solution de cas général à votre problème (celui où chaque tableau interne peut éventuellement avoir des clés uniques).
$final = array();
array_walk_recursive($input, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
Exemple avec array_walk_recursive()
pour le cas général
De plus, depuis PHP 5.5, vous pouvez utiliser la fonction array_column()
pour obtenir le résultat souhaité pour la clé exacte, [gozhi]
_, par exemple :
array_sum(array_column($input, 'gozhi'));
Exemple avec array_column()
pour la clé spécifiée
Si vous voulez obtenir la somme totale de tous les tableaux internes avec les mêmes clés (le résultat souhaité que vous avez publié), vous pouvez faire quelque chose comme ceci (en gardant à l'esprit que le premier tableau doit avoir la même structure que les autres):
$final = array_shift($input);
foreach ($final as $key => &$value){
$value += array_sum(array_column($input, $key));
}
unset($value);
Exemple avec array_column()
dans le cas où tous les tableaux internes ont les mêmes clés
Si vous souhaitez une solution de casse générale en utilisant array_column()
, vous pouvez commencer par obtenir toutes les clés uniques, puis la somme de chaque clé:
$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);
Voici une solution similaire aux deux autres:
$acc = array_shift($arr);
foreach ($arr as $val) {
foreach ($val as $key => $val) {
$acc[$key] += $val;
}
}
Mais cela n’a pas besoin de vérifier si les clés de tableau existent déjà et ne jette pas non plus les avis.
Cela peut aussi être fait en utilisant 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;
}
}
Utilisez cet extrait:
$key = 'gozhi';
$sum = array_sum(array_column($array,$key));
Une autre version, avec quelques avantages ci-dessous.
$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);
}
}
Je souhaitais associer le meilleur des réponses de Gumbo, de Graviton et de Chris J aux objectifs suivants afin de pouvoir l'utiliser dans mon application:
a) Initialisez les clés du tableau 'somme' en dehors de la boucle (Gumbo). Devrait aider à la performance sur les très grands tableaux (pas encore testé!). Élimine les avis.
b) La logique principale est facile à comprendre sans toucher aux manuels. (Graviton, Chris J).
c) Résoudre le problème plus général de l'ajout des valeurs de deux tableaux quelconques avec les mêmes clés et le rendre moins dépendant de la structure du sous-tableau.
Contrairement à la solution de Gumbo, vous pouvez le réutiliser dans les cas où les valeurs ne sont pas dans des sous-tableaux. Imaginez, dans l'exemple ci-dessous, que $arr1
et $arr2
ne soient pas codés en dur, mais sont renvoyés à la suite de l'appel d'une fonction dans une boucle.
$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);
Cela peut aussi être fait en utilisant 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'));
Pas si lisible que les solutions précédentes mais ça marche :)
Voici une version où les clés de tableau peuvent ne pas être les mêmes pour les deux tableaux, mais vous voulez qu'elles soient toutes dans le tableau final.
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;
}
Nous devons d'abord vérifier si la clé de tableau existe.
CODE:
$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 With Array Key Validation:
Array
(
[gozhi] => 10
[uzorong] => 1
[ngangla] => 8
[langthel] => 10
)
OUTPUT sans validation de clé de tableau:
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
)
Ceci est une mauvaise pratique bien qu’il imprime la sortie. Toujours vérifier d'abord si la clé existe.
cela fonctionne très bien sur mon projet laravel
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
Vous pouvez essayer ceci:
$c = array_map(function () {
return array_sum(func_get_args());
},$a, $b);
et enfin:
print_r($c);
Ici vous avez comment je fais habituellement ce genre d'opérations.
// 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);
Parcourez chaque élément du tableau et additionnez les valeurs aux valeurs précédentes si elles existent, sinon attribuez-les.
<?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] = isset($carry[$k]) ? $carry[$k] + $v : $v;
return $carry;
}, []);
print_r($result);
Sortie:
Array
(
[a] => 6
[b] => 3
[c] => 1
[d] => 3
)
Pour ceux qui ont atterri ici et qui recherchent une solution fusionnant les tableaux N ET qui additionne également les valeurs des clés identiques trouvées dans les tableaux N, j'ai écrit cette fonction qui fonctionne également de manière récursive. (Voir: https://Gist.github.com/Nickology/f700e319cbafab5eaedc )
Exemple:
$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));
Aura pour résultat:
Array
(
[A] => tom
[sum] => 30
[C] => Array
(
[0] => x
[1] => y
[z] => 145
[w] => 1
)
)
Voici le code:
<?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 <[email protected]>
* @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;
}
?>