【问题标题】:Laravel Collection with groupby, count and sumLaravel Collection 与 groupby、count 和 sum
【发布时间】:2020-06-24 19:18:19
【问题描述】:

我正在努力让一个集合上的 groupby 起作用 - 我还没有得到这个概念。

我正在为一个玩家从表中提取结果集合,雄辩的集合将包含如下数据:

['player_id'=>1, 'opposition_id'=>10, 'result'=>'won', 'points'=>2],
['player_id'=>1, 'opposition_id'=>11, 'result'=>'lost', 'points'=>0],
['player_id'=>1, 'opposition_id'=>12, 'result'=>'lost', 'points'=>0],
['player_id'=>1, 'opposition_id'=>10, 'result'=>'won', 'points'=>2],
['player_id'=>1, 'opposition_id'=>11, 'result'=>'lost', 'points'=>0],
['player_id'=>1, 'opposition_id'=>10, 'result'=>'lost', 'points'=>0],
['player_id'=>1, 'opposition_id'=>12, 'result'=>'won', 'points'=>2],

我希望能够groupBy('opposition_id'),然后给我一个总结果数、总赢数、总输数和积分总和,最终得到这样的集合:

['opposition_id'=>10, 'results'=>3, 'won'=>2, 'lost'=>1, 'points'=>4],
['opposition_id'=>11, 'results'=>2, 'won'=>0, 'lost'=>2, 'points'=>0],
['opposition_id'=>10, 'results'=>2, 'won'=>1, 'lost'=>1, 'points'=>2]

我试图避免返回数据库来执行此操作,因为我已经获得了之前活动的结果。

我如何使用 Laravel 收集方法来做到这一点,到目前为止,我所拥有的是:

$stats = $results->groupBy('opposition_id');

我查看了map(),但还不了解解决方案的方法

谁能指点我正确的方向。

如果需要,很高兴返回数据库,但假设我可以使用已有的集合来执行此操作,而不是创建另一个查询。我在这里找到的解决方案似乎都在查询中提供了解决方案

谢谢

【问题讨论】:

    标签: laravel collections


    【解决方案1】:

    看看这里,在 cmets 中有解释的工作代码。

    // make a collection
    $c = collect(
        [
            ['player_id' => 1, 'opposition_id' => 10, 'result' => 'won', 'points' => 2],
            ['player_id' => 1, 'opposition_id' => 11, 'result' => 'lost', 'points' => 0],
            ['player_id' => 1, 'opposition_id' => 12, 'result' => 'lost', 'points' => 0],
            ['player_id' => 1, 'opposition_id' => 10, 'result' => 'won', 'points' => 2],
            ['player_id' => 1, 'opposition_id' => 11, 'result' => 'lost', 'points' => 0],
            ['player_id' => 1, 'opposition_id' => 10, 'result' => 'lost', 'points' => 0],
            ['player_id' => 1, 'opposition_id' => 12, 'result' => 'won', 'points' => 2]
        ]
    );
    // this only splits the rows into groups without any thing else.
    // $groups will be a collection, it's keys are 'opposition_id' and it's values collections of rows with the same opposition_id.
    $groups = $c->groupBy('opposition_id'); 
    
    // we will use map to cumulate each group of rows into single row.
    // $group is a collection of rows that has the same opposition_id.
    $groupwithcount = $groups->map(function ($group) {
        return [
            'opposition_id' => $group->first()['opposition_id'], // opposition_id is constant inside the same group, so just take the first or whatever.
            'points' => $group->sum('points'),
            'won' => $group->where('result', 'won')->count(),
            'lost' => $group->where('result', 'lost')->count(),
        ];
    });
    // if you don't like to take the first opposition_id you can use mapWithKeys:
    $groupwithcount = $groups->mapWithKeys(function ($group, $key) {
        return [
            $key =>
                [
                    'opposition_id' => $key, // $key is what we grouped by, it'll be constant by each  group of rows
                    'points' => $group->sum('points'),
                    'won' => $group->where('result', 'won')->count(),
                    'lost' => $group->where('result', 'lost')->count(),
                ]
        ];
    });
    
    // here $groupwithcount will give you objects/arrays keyed by opposition_id:
    [
      10 =>   ["opposition_id" => 10,"points" => 4,"won" => 2,"lost" => 1]
      11 =>   ["opposition_id" => 11,"points" => 0,"won" => 0,"lost" => 2]
      12 =>   ["opposition_id" => 12,"points" => 2,"won" => 1,"lost" => 1]
    ]
    
    // if you use $groupwithcount->values() it'll reset the keys to 0 based sequence as usual:
    [
      0 =>   ["opposition_id" => 10,"points" => 4,"won" => 2,"lost" => 1]
      1 =>   ["opposition_id" => 11,"points" => 0,"won" => 0,"lost" => 2]
      2 =>   ["opposition_id" => 12,"points" => 2,"won" => 1,"lost" => 1]
    ]
    

    【讨论】:

    • 嗨 - 太棒了 - 谢谢。真的很感谢代码上的cmets-一直在学习-谢谢:)
    • 不客气。如果满足问题,则标记为已回答。
    猜你喜欢
    • 2016-10-26
    • 2019-02-02
    • 2019-01-30
    • 2018-02-07
    • 2020-05-19
    • 2013-02-06
    • 2023-03-30
    • 2016-05-06
    • 1970-01-01
    相关资源
    最近更新 更多