web-dev-qa-db-fra.com

Somme des valeurs de tableau multidimensionnel par clé sans boucle

J'ai ceci: 

Array (
    [0] => Array ( [f_count] => 1 [uid] => 105 ) 
    [1] => Array ( [f_count] => 0 [uid] => 106 ) 
    [2] => Array ( [f_count] => 2 [uid] => 107 ) 
    [3] => Array ( [f_count] => 0 [uid] => 108 ) 
    [4] => Array ( [f_count] => 1 [uid] => 109 ) 
    [5] => Array ( [f_count] => 0 [uid] => 110 ) 
    [6] => Array ( [f_count] => 3 [uid] => 111 )
)

Ce dont j'ai besoin, c'est: 7 ", qui est la somme de la colonne f_count.

J'essaie de comprendre cela depuis quelques heures. Je pensais que array_sum() fonctionnerait, mais pas avec un tableau multidimensionnel. J'ai donc essayé de trouver un moyen d'isoler le f_counts par unset(), d'épissure ou autre, mais chaque solution semble comporter une boucle foreach. J'ai joué avec array_map, array_walk et d'autres en vain. Je n'ai pas trouvé de fonction qui fonctionne bien avec les tableaux multidimensionnels.

J'exécute PHP 5.4.

Quelqu'un peut-il me montrer comment additionner cette colonne sans une boucle foreach?

Si cela vous aide, les valeurs f_count ne seront jamais supérieures à 100 et les valeurs uid seront toujours supérieures à 100.


Sinon, s'il existe un moyen d'exécuter ma requête différemment, de sorte que le tableau ne soit pas multidimensionnel, cela fonctionnerait également.

$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array = $stmt->fetchAll();

J'utilise PDO.

21
David

Vous devez l'associer à array_map() pour sélectionner la colonne f_count en premier:

array_sum(array_map(function($item) { 
    return $item['f_count']; 
}, $arr));

Bien entendu, en interne, cela effectue une double boucle; c'est juste que vous ne le voyez pas dans le code. Vous pouvez utiliser array_reduce() pour supprimer une boucle:

array_reduce($arr, function(&$res, $item) {
    return $res + $item['f_count'];
}, 0);

Cependant, si la vitesse est le seul intérêt, foreach reste le plus rapide:

$sum = 0;
foreach ($arr as $item) {
    $sum += $item['f_count'];
}

Ceci est dû à la "localité" des variables que vous utilisez, c’est-à-dire qu’aucun appel de fonction n’est utilisé pour calculer la somme finale.

56
Ja͢ck

En php 5.5+, vous pouvez simplement utiliser array_column et array_sum comme suit:

 $value = array_sum(array_column($arr,'f_count'));
61
Anthony Harley

pour ce type de situation, la boucle foreach est la meilleure option possible, mais si vous devez le faire plusieurs fois sur une seule page, vous devriez mettre la boucle foreach dans une fonction afin que votre code reste propre.

function sum_index($arr, $col_name){
    $sum = 0;
    foreach ($arr as $item) {
        $sum += $item[$col_name];
    }
    return $sum;
}

Modifier

Après avoir cherché beaucoup, j'ai trouvé que la fonction array_column existait dans PHP 5.5 + pour obtenir toutes les valeurs d'une colonne en tant que tableau.

Pour les utilisateurs ayant une version inférieure Vous pouvez utiliser la fonction suivante et l’appeler avec tableau somme si vous voulez aussi faire la somme de toutes les valeurs.

//to get all values of single column from multidimensional array, this function exist in php 5.5 or greater.
if(!function_exists("array_column"))
{
    function array_column($array,$column_name)
    {
        return array_map(function($element) use($column_name){return $element[$column_name];}, $array);
    }
}

Si vous voulez obtenir toutes les valeurs d'une colonne, alors appelez la fonction ci-dessus comme ceci:

$newArray = array_column($array,$column_name);

Si vous voulez la somme de toutes les valeurs d'une colonne, utilisez le code suivant:

$newArraySum = array_sum(array_column($array,$column_name));
1
Raja Imran Qamer

Sinon, s'il existe un moyen d'exécuter ma requête différemment, tel que le tableau n'est pas multidimensionnel, cela fonctionnerait évidemment aussi.

$query = "SELECT f_count, uid FROM users WHERE gid=:gid"; 
... 
$array = $stmt->fetchAll(); 

J'utilise PDO.

Oui, il existe un autre moyen d’exécuter votre requête différemment. Vous pouvez utiliser la fonction d'agrégation SUM pour obtenir la somme de tous les f_count directement dans votre requête. Vous combinerez ceci avec $stmt->fetchColumn() pour obtenir la valeur de la première colonne (qui serait la somme) de la première ligne (qui sera la seule ligne puisque nous avons utilisé une fonction d'agrégat).

Voici un exemple de la façon dont vous pourriez faire cela:

$query = "SELECT SUM(f_count) FROM users WHERE gid=:gid";
$stmt = $pdo->prepare($query);
$stmt->execute(array(':gid' => 'yoursearchvalue'));
$sum = $stmt->fetchColumn();
1
Kodos Johnson

Puisque vous utilisez PHP 5.4 avec PDO, il pourrait y avoir un autre moyen de le faire (disponible dans PHP 5.1+):

  • utilisez la fonction PDO fetchAll() avec le PDO::FETCH_COLUMN en tant que fetch_style et le numéro de colonne indexé par 0 en tant que fetch_argument.

Selon votre exemple, cela pourrait être:

$query = "SELECT f_count, uid FROM users WHERE gid=:gid";
...
$array_fcount = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);

Maintenant, utilisez la fonction array_sum pour additionner les valeurs du tableau:

$fcount_sum = array_sum($array_fcount);

Vous pouvez également consulter la documentation PHP sur http://php.net/manual/en/pdostatement.fetchall.php

J'espère que cela aide, et la performance pourrait être meilleure que la boucle! Comme déjà mentionné dans d'autres réponses, dans PHP 5.5, vous avez la fonction array_column() pour obtenir $array_fcount directement à partir d'un autre tableau.

0
kpk