Laravel 数组分组并合并每个组

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

我有这样一个数组,如何按

date
分组并合并每个组?

$input =  [
    [
        'date' => '2018-09-25',
        'foo' => 'value1',
    ],
    [
        'date' => '2018-09-25',
        'bar' => 'value2'
    ],
    [
        'date' => '2018-09-26',
        'baz' => 'value3'
    ]
];

最后结果是这样的:

[
    [
        'date' => '2018-09-25'
        'foo' => 'value1'
        'bar' => 'value2'
    ],
    [
        'date' => '2018-09-26'
        'baz' => 'value3'
    ]
]
php arrays laravel grouping laravel-collection
2个回答
7
投票

您可以使用 laravel collection

首先需要通过 groupBy 方法进行分组,然后 map 每个组并合并每个子数组。

代码:

$result = collect($input)
    ->groupBy('date')
    ->map(function ($item) {
        return array_merge(...$item->toArray());
    });

您将获得此收藏品:

最后删除键(日期),您可以使用values,然后简单地将集合转换为数组(toArray)。

结束代码:

$result = collect($input)
    ->groupBy('date')
    ->map(function ($item) {
        return array_merge(...$item->toArray());
    })
    ->values()
    ->toArray();

0
投票

要将二维数组中的行数据分组到单个循环中,请使用

foreach()
array_reduce()
以及引用数组,以避免将临时第一级键应用于结果数组。

虽然比将多个 Laravel 集合方法链接在一起在视觉上不太优雅,但只有一个循环用于直接实现结果。比较一下它可以调用几个底层循环:

collect()
groupBy()
map()
array_merge()
values()
,然后是
toArray()

代码:(演示

$result = [];
foreach ($input as $row) {
    $date = $row['date'];
    if (!isset($ref[$date])) {
        $ref[$date] = $row;
        $result[] =& $ref[$date];
        continue;
    }
    $ref[$date] += $row;
}
var_export($result);

功能风格的等价物:(Demo)

var_export(
    array_reduce(
        $input,
        function ($result, $row) {
            static $ref = [];
            $date = $row['date'];
            if (!isset($ref[$date])) {
                $ref[$date] = $row;
                $result[] =& $ref[$date];
            } else {
                $ref[$date] += $row;
            }
            return $result;
        }
    )
);

如果您对性能争论不感兴趣,那么下面的脚本将简洁地链接@ИльяЗелень的答案。这消除了展平每个组时不需要的

toArray()
调用并使用箭头函数语法。 (PHPize 演示)

var_export(
    collect($input)
    ->groupBy('date')
    ->map(fn($group) => array_merge(...$group))
    ->values()
    ->toArray()
);
© www.soinside.com 2019 - 2024. All rights reserved.