Laravel如何反转集合层级 将事件带订阅者转为订阅者带关联事件
更简洁的实现方案
方案1:PHP 7.4+ 短闭包版本(最推荐,可读性最高)
直接用only方法主动提取需要的字段代替unset破坏性操作,配合短闭包大幅简化代码:
$subscribers = $subscriptions->groupBy('subscriber.id') ->map(fn($group) => array_merge( $group->first()['subscriber'], ['subscriptions' => $group->map(fn($sub) => collect($sub)->only('id', 'event'))] ))->values();
如果你的集合项本身是对象而非数组,把数组访问改成箭头访问即可:$group->first()->subscriber。
提示:如果需要最终结果为纯数组而非Laravel集合,可在调用
values()后追加->toArray()。
方案2:兼容低版本PHP写法
如果不支持短闭包,替换为普通闭包即可:
$subscribers = $subscriptions->groupBy('subscriber.id') ->map(function ($group) { return array_merge( $group->first()['subscriber'], ['subscriptions' => $group->map(function ($sub) { return collect($sub)->only('id', 'event'); })] ); })->values();
方案3:更高性能的reduce版本(适合数据量较大的场景)
只遍历一次集合完成分组和结构转换,比groupBy+map少一次遍历,数据量越大性能优势越明显:
$subscribers = $subscriptions->reduce(function ($carry, $subscription) { $subscriberId = $subscription['subscriber']['id']; if (!isset($carry[$subscriberId])) { $carry[$subscriberId] = $subscription['subscriber'] + ['subscriptions' => []]; } $carry[$subscriberId]['subscriptions'][] = collect($subscription)->only('id', 'event'); return $carry; }, collect())->values();
内容的提问来源于stack exchange,提问作者amcardwell
相关产品推荐
相关产品推荐

