如何在Laravel中将数组内对象的值转换为指定键名的关联数组?
Laravel 数组格式转换与查询优化
一、先修正原查询的错误
你的原查询最后一个union存在两处错误:表别名使用D但仍用p引用字段,且where条件错误指向C,导致结果重复且顺序不符。修正后的查询如下:
$filter = ["A","B","C","D"]; if(user()->hasRole('admin')){ $projects = DB::table('projects AS p') ->select(DB::raw('count(p.id) as count')) ->where('p.alphabet','=','A') ->union(DB::table('projects AS p') ->select(DB::raw('count(p.id) as count')) ->where('p.alphabet','=','B')) ->union(DB::table('projects AS p') ->select(DB::raw('count(p.id) as count')) ->where('p.alphabet','=','C')) ->union(DB::table('projects AS p') ->select(DB::raw('count(p.id) as count')) ->where('p.alphabet','=','D')); }
不过这种多次union的写法效率较低,更推荐用group by一次性统计,直接得到目标格式:
$filter = ["A","B","C","D"]; if(user()->hasRole('admin')){ // 按alphabet分组统计已有数据 $counts = DB::table('projects AS p') ->select('p.alphabet', DB::raw('count(p.id) as count')) ->whereIn('p.alphabet', $filter) ->groupBy('p.alphabet') ->pluck('count', 'alphabet') ->toArray(); // 补全filter中未统计到的字母,默认count为0 $result = array_merge(array_fill_keys($filter, 0), $counts); }
二、现有结果数组转换方法
如果已经拿到原查询返回的对象数组,用Laravel集合工具可以快速转换:
$originalArray = $projects->get()->toArray(); $filter = ["A","B","C","D"]; // 提取所有count值并与filter组合成关联数组 $counts = collect($originalArray)->pluck('count')->toArray(); $result = array_combine($filter, $counts); // 若原数组顺序与期望不符,手动指定映射关系 // $result = [ // 'A' => $originalArray[0]->count, // 'B' => $originalArray[1]->count, // 'C' => $originalArray[3]->count, // 'D' => $originalArray[2]->count, // ];
也可以用集合的mapWithKeys链式处理:
$result = collect($originalArray) ->zip($filter) ->mapWithKeys(function ($item) { return [$item[1] => $item[0]->count]; }) ->toArray();
注意点
- 若原查询结果顺序和
$filter不匹配,需手动对应键值或调整查询逻辑保证顺序一致。 - 分组统计的方式比多次
union性能更优,数据量大时差异明显。
内容的提问来源于stack exchange,提问作者aliii
相关产品推荐
相关产品推荐

