【问题标题】:Sum values of multidimensional array by key without loop无循环按键对多维数组的值求和
【发布时间】:2013-04-14 20:10:22
【问题描述】:

我有这个:

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_counts,但每个解决方案似乎都涉及foreach 循环。我已经搞砸了array_maparray_walk 和其他人无济于事。我还没有找到适用于多维数组的函数。

我正在运行 PHP 5.4。

有人可以告诉我如何在没有foreach 循环的情况下对该列求和吗?

如果有帮助,f_count 的值将永远不会高于 100uid 的值将始终大于 100


或者,如果有办法以不同的方式运行我的查询以使数组不是多维的,那显然也可以。

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

我正在使用 PDO。

【问题讨论】:

  • 如果没有循环,您将无法对数组执行任何操作。为什么这么反感?

标签: php mysql arrays multidimensional-array


【解决方案1】:

或者,如果有办法以不同的方式运行我的查询,例如 该数组不是多维的,这显然也可以。

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

我正在使用 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();

【讨论】:

    【解决方案2】:

    由于您使用的是带有 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);
    

    您也可以在http://php.net/manual/en/pdostatement.fetchall.php 查阅 PHP 文档

    希望这会有所帮助,并且性能可能比循环更好!正如其他答案中已经提到的那样,在 PHP 5.5 及更高版本中,您可以使用 array_column() 函数直接从另一个数组中获取 $array_fcount

    【讨论】:

      【解决方案3】:

      对于这些类型的情况,foreach 循环是最好的选择,但如果您必须在一个页面上多次执行此操作,那么您应该将 foreach 循环放在一个函数中,以便您的代码保持干净

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

      编辑

      经过大量搜索,我发现array_column 函数存在于 php 5.5 + 中,用于将单列的所有值作为数组获取。

      对于版本较低的用户,如果您还想要所有值的总和,您可以使用以下函数并使用数组 sum 调用它。

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 谢谢伙计,现在我可以睡个好觉了。我的版本不是求和,而只是计数,所以我使用这个函数 => $value = array_count_values(array_column($arr,'f_count'));
        • "... 多维数组 ..." 如果深度是 3,那该怎么办?
        • 太棒了,谢谢朋友。
        【解决方案5】:

        您需要先将其与array_map() 耦合才能选择f_count 列:

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

        当然,在内部,这执行了一个双循环;只是您在代码中看不到它。您可以使用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'];
        }
        

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

        【讨论】:

        • 我并没有太冒昧地认为这些选项可能比 foreach 更有效?
        • @David 不,它们的效率都低于foreach
        • 我想我被误导了。谢谢你的澄清。
        • 如果我能想出一个比我见过的其他人更漂亮、更简单的foreach,我会给你一个奖励。再次感谢。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-30
        • 1970-01-01
        • 2023-03-23
        相关资源
        最近更新 更多