按多个列值对数组行进行分组,并对每组中的另一列求和


Group array rows by multiple column values and sum another column within each group

我正试图将关联数组数组中的数据按三列(yearmonthgrupo)进行分组,并对另一列进行求和(quantity)。

给定一个数组,如:

$in = [
    ['year' => '2010', 'month' => '11', 'grupo' => '2', 'quantity' => 3],
    ['year' => '2010', 'month' => '11', 'grupo' => '3', 'quantity' => 4],
    ['year' => '2011', 'month' => '2', 'grupo' => '2', 'quantity' => 4],
    ['year' => '2011', 'month' => '2', 'grupo' => '2', 'quantity' => 4],
    ['year' => '2012', 'month' => '3', 'grupo' => '4', 'quantity' => 3]
    ['year' => '2012', 'month' => '3', 'grupo' => '4', 'quantity' => 3]
];

我想要:

[
    ['year' => '2010', 'month' => '11', 'grupo' => '2', 'quantity' => 3],
    ['year' => '2010', 'month' => '11', 'grupo' => '3', 'quantity' => 4],
    ['year' => '2011', 'month' => '2', 'grupo' => '2', 'quantity' => 8],
    ['year' => '2012', 'month' => '3', 'grupo' => '4', 'quantity' => 6]
]

我试过这样的东西:

$out = array();
foreach ($in as $row) {
    if (!isset($out[$row['year']['month']['grupo']])) {
        $out[$row['year']['month']['grupo']] = array(
            'year' => $row['year'],
            'month' => $row['month'],
            'grupo' => $row['grupo'],
            'quantity' => 0,
        );
    }
    $out[$row['year']['month']['grupo']]['quantity'] += $row['quantity'];
}
$out = array_values($out);

但是在尝试对3个字段进行分组时失败。

我认为前面的答案忽略了所需的结果——@hellcode和@Rasclatt的解决方案创建了不必要的深层结构。

问题中的编码尝试非常接近正确,只有在第一级生成唯一分组密钥时存在缺陷。

要生成唯一的分组键,必须从行中的多个标识值中伪造一个字符串。换句话说;撰写";三个目标列值中的一个唯一值——一个组合键。

代码:(演示)

$result = [];
foreach ($in as $row) {
    $compositeKey = implode(array_slice($row, 0, 3));
    if (!isset($result[$compositeKey])) {
        $result[$compositeKey] = $row;
    } else {
        $result[$compositeKey]['quantity'] += $row['quantity'];
    }
}
var_export(
    array_values($result)
);

试试这个:

$out = array();
foreach ($in as $row) {
    if(! isset($out[$row['year']][$row['month']][$row['grupo']])) {
        $out[$row['year']][$row['month']][$row['grupo']]=0;
    }
    $out[$row['year']][$row['month']][$row['grupo']] += $row['quantity'];
}
print_r($out);

它将输出您想要的值,但作为多维值数组,而不是具有键=>值对的平面数组:

Array
(
    [2010] => Array
        (
            [11] => Array
                (
                    [2] => 3
                    [3] => 4
                )
        )
    [2011] => Array
        (
            [2] => Array
                (
                    [2] => 8
                )
        )
    [2012] => Array
        (
            [3] => Array
                (
                    [4] => 6
                )
        )
)

但你可以重新排列你的阵列:

$out2 = array();
foreach($out as $year => $year_array) {
  foreach($year_array as $month => $month_array) {
    foreach($month_array as $grupo => $quantity) {
      $out2[] = array('year' => $year, 'month' => $month, 'grupo' => $grupo, 'quantity' => $quantity);
    }
  }
}
print_r($out2);

这将输出:

Array
(
    [0] => Array
        (
            [year] => 2010
            [month] => 11
            [grupo] => 2
            [quantity] => 3
        )
    [1] => Array
        (
            [year] => 2010
            [month] => 11
            [grupo] => 3
            [quantity] => 4
        )
    [2] => Array
        (
            [year] => 2011
            [month] => 2
            [grupo] => 2
            [quantity] => 8
        )
    [3] => Array
        (
            [year] => 2012
            [month] => 3
            [grupo] => 4
            [quantity] => 6
        )
)

这将保留值并给出和。

foreach($in as $row) {
            $out[$row['year']][$row['month']][$row['grupo']]['quantity'][]  =   $row['quantity'];
            $out[$row['year']][$row['month']][$row['grupo']]['sum']         =   array_sum($out[$row['year']][$row['month']][$row['grupo']]['quantity']);
        }
print_r($out);

给予

Array
(
    [2010] => Array
        (
            [11] => Array
                (
                    [2] => Array
                        (
                            [quantity] => Array
                                (
                                    [0] => 3
                                )
                            [sum] => 3
                        )
                    [3] => Array
                        (
                            [quantity] => Array
                                (
                                    [0] => 4
                                )
                            [sum] => 4
                        )
                )
        )
    [2011] => Array
        (
            [2] => Array
                (
                    [2] => Array
                        (
                            [quantity] => Array
                                (
                                    [0] => 4
                                    [1] => 4
                                )
                            [sum] => 8
                        )
                )
        )
    [2012] => Array
        (
            [3] => Array
                (
                    [4] => Array
                        (
                            [quantity] => Array
                                (
                                    [0] => 3
                                    [1] => 3
                                )
                            [sum] => 6
                        )
                )
        )
)