我有这样一个数组,如何按
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'
]
]
您可以使用 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();
要将二维数组中的行数据分组到单个循环中,请使用
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()
);