Home » Php » php – Sum values of multidimensional array by key without loop

php – Sum values of multidimensional array by key without loop

Posted by: admin April 23, 2020 Leave a comment

Questions:

I have this:

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

What I need is: 7“, which is the the sum of the f_count column.

I’ve been trying to figure this out for a couple hours. I thought array_sum() would work, but not with a multidimensional array. So, I’ve tried figuring out how to isolate the f_counts by unset() or splicing or anything else, but every solution seems to involve a foreach loop. I’ve messed with array_map, array_walk, and others to no avail. I haven’t found a function that works well with multidimensional arrays.

I’m running PHP 5.4.

Can someone please show me how to sum that column without a foreach loop?

If it helps, the f_count values will never be higher than 100, and the uid values will always be greater than 100.


Alternatively, if there’s a way to run my query differently such that the array is not multidimensional, that would obviously work as well.

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

I’m using PDO.

How to&Answers:

You need to couple it with array_map() to select the f_count column first:

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

Of course, internally, this performs a double loop; it’s just that you don’t see it inside the code. You could use array_reduce() to get rid of one loop:

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

However, if speed is the only interest, foreach remains the fastest:

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

This is thanks to the “locality” of the variables that you’re using, i.e. there are no function calls used to calculate the final sum.

Answer:

In php 5.5+ you can just used array_column and array_sum like so:

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

Answer:

for these type of situation foreach loop is the best possible option but if u have to do this for multiple times on a single page then u should put foreach loop in a function so that your code remain clean

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

Edit

After searching alot I found that array_column function exist in php 5.5 + to get all values of single column as an array.

For users having lower version You can use following function and call it with array sum if you want sum of all values as well.

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

If you want to get all values of single column then call above function like this:

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

If you want sum of all values of single column then use following code:

$newArraySum = array_sum(array_column($array,$column_name));

Answer:

Alternatively, if there’s a way to run my query differently such that
the array is not multidimensional, that would obviously work as well.

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

I’m using PDO.

Yes, there is another way to run your query differently. You could use the aggregate function SUM to get the sum of all the f_count directly in your query. You would combine this with $stmt->fetchColumn() to get the value of the first column (which would be the sum) of the first row (which will be the only row since we used an aggregate function).

Here is an example of how you could do this:

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

Answer:

Since you are using PHP 5.4 with PDO, there could be one more way to do it (available in PHP 5.1+):

  • use the PDO fetchAll() function with the PDO::FETCH_COLUMN as the fetch_style, and the 0-indexed column number as the fetch_argument.

As per your example, it could be:

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

Now use the array_sum function to sum the values of the array:

$fcount_sum = array_sum($array_fcount);

You could also consult the PHP documentation at http://php.net/manual/en/pdostatement.fetchall.php

Hope this helps, and the performance could be better than looping! As already mentioned in other answers, in PHP 5.5 onwards you have the array_column() function to get $array_fcount directly from another array.