Laravel如何合并多个Collection并按date字段融合数据项?
Laravel 按date字段合并多个Collection的解决方案
需求说明
现有三个Laravel Collection,需要创建新集合,将相同date字段的数组项合并,融合所有关联字段。
原始数据
$data1= new Collection( [ [ "date" => "2022-09-07", "address" => 1 ], [ "date" => "2022-08-11", "address" => 1 ] ]); $data2= new Collection( [ [ "date" => "2022-09-10", "gender" => 5 ], [ "date" => "2022-08-11", "gender" => 20 ], [ "date" => "2022-08-06", "gender" => 9 ] ]); $data3= new Collection( [ [ "date" => "2022-09-10", "animal" => 10 ], ]);
期望结果
^ array:4 [ 0 => array:2 [ "date" => "2022-09-07" "address" => 1 ] 1 => array:3 [ "date" => "2022-08-11" "address" => 1, "gender" => 20, ] 2 => array:3 [ "date" => "2022-09-10" "gender" => 5 "animal" => 10 ] 3 => array:2 [ "date" => "2022-08-06" "gender" => 9 ] ]
注:原期望结果中的age应为笔误,实际对应gender字段
尝试过的无效方法
使用merge或union无法实现按date合并字段的需求,结果不符合预期:
merge方法结果
$resultMerge = $data1->merge($data2); $resultMerge = $resultMerge->merge($data3); // 输出结果: ^ array:6 [ 0 => array:2 [ "date" => "2022-09-07" "address" => 1 ] 1 => array:2 [ "date" => "2022-08-11" "address" => 1 ] 2 => array:2 [ "date" => "2022-09-10" "gender" => 5 ] 3 => array:2 [ "date" => "2022-08-11" "gender" => 20 ] 4 => array:2 [ "date" => "2022-08-06" "gender" => 9 ] 5 => array:2 [ "date" => "2022-09-10" "animal" => 10 ] ]
union方法结果
$resultUnion = $data1->union($data2); $resultUnion = $resultUnion->union($data3); // 输出结果: ^ array:3 [ 0 => array:2 [ "date" => "2022-09-07" "address" => 1 ] 1 => array:2 [ "date" => "2022-08-11" "address" => 1 ] 2 => array:2 [ "date" => "2022-08-06" "gender" => 9 ] ]
可行解决方案
通过concat合并所有集合元素,再按date分组,最后合并每组内的数组字段:
代码实现
// 合并所有集合的元素到一个集合中 $combined = $data1->concat($data2)->concat($data3); // 按date分组,合并每组内的所有数组 $result = $combined->groupBy('date')->map(function ($items) { return $items->reduce(function ($carry, $item) { // 合并当前项到累计结果中 return array_merge($carry, $item); }, []); })->values(); // 移除分组的date键,恢复索引顺序 // 输出结果(转为数组) dd($result->toArray());
代码说明
- concat:将三个集合的所有元素合并为一个集合,不会像
merge那样替换同索引元素,保留所有原始项。 - groupBy('date'):按
date字段对集合元素分组,相同date的项会被分到同一组。 - map + reduce:遍历每个分组,用
reduce将组内的所有数组合并成一个数组,自动融合不同字段。 - values():移除分组后的date键,将集合恢复为连续索引的结构,符合期望结果的格式。
内容的提问来源于stack exchange,提问作者Alexd2
相关产品推荐
相关产品推荐

