将二维数组按一列分组,并对每组内的多列求和

问题描述 投票:0回答:3

我需要将二维数组中的行数据按一列进行分组,然后分别对其他列进行求和,以生成一个行数可能更少的新二维数组。

就我而言,我需要按每个

[num]
计算
[price]
[group]
的总和。

[
    ['group' => 'Apple', 'num' => 5, 'price' => 10],
    ['group' => 'Apple', 'num' => 2, 'price' => 8],
    ['group' => 'Orange', 'num' => 4, 'price' => 6],
    ['group' => 'Orange', 'num' => 12, 'price' => 24],
]

结果会是这样的:

[
    ['group' => 'Apple', 'num' => 7, 'price' => 18],
    ['group' => 'Orange', 'num' => 16, 'price' => 30],
]
php arrays multidimensional-array sum grouping
3个回答
2
投票

简单的循环和关联数组就可以完成这项工作:

$result = Array();
foreach($array as $row) {
   if(!isset($result[ $row['group'] ])) {
       $result[ $row['group'] ] = $row;
       continue ;
   }
   $result[ $row['group'] ]['num'] += $row['num'];
   $result[ $row['group'] ]['price'] += $row['price'];
}
$result = array_values($result);

1
投票

使用

array_reduce()

$reduced = array_reduce($array, function(&$result, $item){
    $result[$item['group']]['num'] += $item['num'];
    $result[$item['group']]['price'] += $item['price'];
    return $result;
});

0
投票

通过将引用变量推入每个唯一组的结果数组中,循环后无需重新索引结果数组。

代码:(演示

$result = [];
foreach ($array as $row) {
    if (!isset($ref[$row['group']])) {
        $ref[$row['group']] = $row;
        $result[] =& $ref[$row['group']];
        continue;
    }
    $ref[$row['group']]['num'] += $row['num'];
    $ref[$row['group']]['price'] += $row['price'];
}
var_export($result);

作为 @Peter 解决方案的替代实现,在调用

array_values()
(运行另一个内部循环)重新索引结果之前,可以将每行的各个值单独推入结果数组中。

代码:(演示

$result = [];
foreach ($array as ['group' => $g, 'num' => $n, 'price' => $p]) {
    $result[$g]['group'] = $g;
    $result[$g]['num'] = ($result[$g]['num'] ?? 0) + $n;
    $result[$g]['price'] = ($result[$g]['price'] ?? 0) + $p;
}
var_export(array_values($result));

最后,此页面上任何带有

foreach()
循环的工作实现都可以使用
array_reduce()
适当地转录为函数式风格。这有点冗长,但消除了向全局范围添加临时变量的情况。

代码:(演示

var_export(
    array_values(
        array_reduce(
            $array,
            function ($result, $row) {
                if (!isset($result[$row['group']])) {
                    $result[$row['group']] = $row;
                } else {
                    $result[$row['group']]['num'] += $row['num'];
                    $result[$row['group']]['price'] += $row['price'];
                }
                return $result;
            }
        )
    )
);
© www.soinside.com 2019 - 2024. All rights reserved.