如何对嵌套Laravel集合按groupBy修改并保留键名格式
Laravel嵌套集合按master_id分组并保留原键名的解决方案
问题场景
现有如下结构的集合数据:
{ "document": [ { "id": 1, "company_id": 4, "client_id": 1, "status": 1, "client": { "id": 1, "company_id": 4, "name": "1663159185735-client" }, "document_items": [ { "id": 1, "master_id": 5, "text_value": "piyo" }, { "id": 2, "master_id": 5, "text_value": "fuga" }, { "id": 3, "master_id": 3, "text_value": "hoge" } ] } ] }
期望将document_items按master_id分组,最终结构如下:
{ "document": [ { "id": 1, "company_id": 4, "client_id": 1, "status": 1, "client": { "id": 1, "company_id": 4, "name": "1663159185735-client" }, "document_items": { "5": [ { "id": 1, "master_id": 5, "text_value": "piyo" }, { "id": 2, "master_id": 5, "text_value": "fuga" } ], "3": [ { "id": 3, "master_id": 3, "text_value": "hoge" } ] } } ] }
遇到的问题
尝试以下代码时,输出键为documentItems而非目标的document_items:
$result->map(function ($v){ $v->documentItems = $v->documentItems->groupBy('master_id'); return $v; });
修改为直接赋值给document_items后,出现键名异常且分组未正确生效:
$result->map(function ($v){ $v->document_items = $v->documentItems->groupBy('master_id'); return $v; });
解决方案
情况1:$result是Eloquent模型集合
如果$result是Eloquent模型实例的集合,documentItems是定义的关联关系,需要使用setAttribute方法来正确赋值蛇形命名的属性:
$result->map(function ($item) { // 从关联关系获取documentItems集合,按master_id分组后赋值给document_items属性 $item->setAttribute('document_items', $item->documentItems->groupBy('master_id')); return $item; });
情况2:$result是普通数组集合
如果$result是普通的数组集合(非Eloquent模型),直接通过数组键名访问并处理即可:
$result->map(function ($item) { // 将document_items转为集合后按master_id分组,重新赋值回原键 $item['document_items'] = collect($item['document_items'])->groupBy('master_id'); return $item; });
补充说明
- Laravel Eloquent模型中,蛇形命名的数据库字段对应驼峰命名的访问器/关联关系,直接赋值蛇形属性时,使用
setAttribute可以避免属性与关联关系的命名冲突。 - 分组后的结果是关联数组(集合),而非原结构中的索引数组,这是
groupBy方法的预期行为,符合你期望的键值对分组格式。
内容的提问来源于stack exchange,提问作者dmnlk
相关产品推荐
相关产品推荐

