Laravel之Collection::macro

我们model查询数据时,经常遇到需要多个分组条件的情况,如果我们想得到根据分组条件组合的kv数据,laravel集合自带keyBy方法对于这种情况处理起来较麻烦些,下面让我们通过macro方法扩展一个集合方法简化处理

// 在合适的地方如:AppServiceProvider扩展集合方法
// 该方法允许指定多个key作为集合的键
// 并且可以通过类似$col->get('k1.k2.k3')这种形式访问集合
Collection::macro('multiKeyBy', function (...$keys) {
    return $this->keyBy(function ($c) use($keys) {
        $tmp = [];
        foreach ($keys as $k) {
            $tmp[] = $c->{$k};
        }
        return implode('.', $tmp);
    });
});

// 数据查询时快捷调用
$group = ['app_id', 'game_id'];
$data = Order::selectRaw('app_id, game_id, sum(money) as money')
    ->groupBy($group)->get()
    ->multiKeyBy(...$group);
dd($data->toArray());
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 2

groupBy()可以传入一个回调函数来处理 key 值,不知道你想要的是不是这样的结果:

$data = collect([
    ['id' => 1, 'type' => 1, 'status' => 1],
    ['id' => 2, 'type' => 1, 'status' => 1],
    ['id' => 3, 'type' => 1, 'status' => 2],
]);

$res = $data->groupBy(function ($item) {
    return sprintf('%s.%s', $item['type'], $item['status']);
});

dd($res->get('1.2'), $res->toArray());

结果:

Illuminate\Support\Collection {#3549 // app/Console/Commands/Test.php:57
  #items: array:1 [
    0 => array:3 [
      "id" => 3
      "type" => 1
      "status" => 2
    ]
  ]
  #escapeWhenCastingToString: false
}
array:2 [ // app/Console/Commands/Test.php:57
  "1.1" => array:2 [
    0 => array:3 [
      "id" => 1
      "type" => 1
      "status" => 1
    ]
    1 => array:3 [
      "id" => 2
      "type" => 1
      "status" => 1
    ]
  ]
  "1.2" => array:1 [
    0 => array:3 [
      "id" => 3
      "type" => 1
      "status" => 2
    ]
  ]
]
1个月前 评论
Poly (楼主) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!