按键对多维数组的值求和,无需循环

53
我有这个:
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 )
)

我需要的是: "7",它是f_count列的总和。
我已经尝试了几个小时,但仍无法解决。我认为array_sum()可以解决问题,但不能用于多维数组。因此,我尝试通过unset()、切片或其他任何方法来隔离f_count,但每个解决方案似乎都涉及到foreach循环。我已经尝试过array_maparray_walk和其他函数,但都没有成功。我还没有找到适用于多维数组的函数。
我正在运行PHP 5.4。
有人能告诉我如何在不使用foreach循环的情况下求和该列吗?
如果有帮助的话,f_count值永远不会超过100,而uid值将始终大于100

或者,如果有一种不使用多维数组的方式来运行我的查询,那显然也可以工作。

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

我正在使用PDO。


1
你如果不用循环,就无法对数组进行任何操作。你为什么这么反感它呢? - deceze
5个回答

119

在php 5.5+中,您可以像这样使用array_columnarray_sum

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

谢谢,现在我可以安心睡觉了。我的版本不是求和,而是计数,所以我使用这个函数 => $value = array_count_values(array_column($arr,'f_count')); - Nova Herdi Kusumah
5
“...多维数组...”如果深度是3,会怎样? - Fr0zenFyr

107
你需要将它与array_map()配合使用,先选择f_count列:
array_sum(array_map(function($item) { 
    return $item['f_count']; 
}, $arr));

如今,您可以使用array_column()替换内部函数:

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

当然,在内部,这执行了一个双重循环;只是你在代码中看不到它。你可以使用 array_reduce() 来消除其中一个循环:

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

然而,如果速度是唯一要考虑的因素,foreach仍然是最快的:

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

这要归功于您使用的变量的“局部性”,即没有使用函数调用来计算最终总和。


2
我认为这些选项比foreach更有效,这并不过分自信吧? - David
6
不,它们都比“foreach”不够高效。 - Ja͢ck
我想我被误导了。谢谢你的澄清。 - David
2
如果我能的话,我会给你一个奖金,因为你提出了一个比我看到的其他foreach更漂亮、更简单的方法。再次感谢。 - David

2

在这种情况下,foreach循环是最好的选择,但如果您需要在单个页面上多次执行此操作,则应将foreach循环放入函数中,以使您的代码保持清洁。

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

编辑

在搜索了很多之后,我发现在php 5.5+中存在array_column函数以获取单列的所有值作为数组。

对于具有较低版本的用户,您可以使用以下函数,并在需要所有值的总和时调用它。

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

如果您想获取单个列的所有值,则可以按照以下方式调用上述函数:
$newArray = array_column($array,$column_name);

如果您想要获得单列所有值的总和,请使用以下代码:
$newArraySum = array_sum(array_column($array,$column_name));

1

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.

是的,有另一种方法可以不同地运行您的查询。您可以使用聚合函数 SUM 直接在查询中获取所有 f_count 的总和。您将与 $stmt->fetchColumn() 结合使用,以获取第一列(即总和)的值,该列为第一行(因为我们使用了聚合函数,所以只有一行)。

以下是如何执行此操作的示例:

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

0

由于您正在使用带有PDO的PHP 5.4,可能还有一种方法可以实现(在PHP 5.1+中可用):

  • 使用PDO fetchAll()函数,并将PDO::FETCH_COLUMN作为fetch_style,将0索引列号作为fetch_argument

根据您的示例,代码如下:

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

现在使用array_sum函数来求和数组的值:

$fcount_sum = array_sum($array_fcount);

你也可以查阅 PHP 文档 http://php.net/manual/zh/pdostatement.fetchall.php
希望这可以帮到你,而且性能可能比循环要好!正如其他答案中已经提到的,在 PHP 5.5 及以上版本中,您可以使用 array_column() 函数直接从另一个数组中获取 $ array_fcount

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接