Laravel对收藏品进行排序,然后按钥匙排序

2022-08-30 18:17:50

我正在为我的用户制作佣金系统,这是我到目前为止所拥有的:

获取所有用户并按点对它们进行排序 - 它工作正常。

$users = User::all();
$users = $users->sortByDesc(function($item){
    return $item->points()->sum('amount');
});

在排名中找到您的位置 - 它工作正常

$position = 0;
foreach($users as $user){
    if(Auth::user()->id == $user->id) break;
    $position++;
}

让自己和用户在我之上/之下 - 这不起作用。我得到随机用户。看起来集合不再排序。

$myRank = new Collection();
if($position > 9){
    $myRank->add($users->get($position-1));
    $myRank->add($users->get($position));
    $myRank->add($users->get($position+1));
    return view('rank.show', ['topTen' => $users->take(15), 'myRank' => $myRank]);
}

请帮我这个或给一些关于另一种方法的提示(许多记录的轻量级)


答案 1

我认为问题是这样的:

当你打电话时,你会得到这样的东西:User::all()

0 => points: 10
1 => points: 50
2 => points: 30
3 => points: 70
4 => points: 20

然后使用 sortBy 函数,该函数对集合重新排序,但不重置键。所以你最终会得到这样的东西:

3 => points: 70
1 => points: 50
2 => points: 30
4 => points: 20
0 => points: 10

因此,在这里使用位置 -1、位置和位置 +1 毫无意义。

您可以做的是使用 values() 函数,这将重置您收集的密钥:

0 => points: 70
1 => points: 50
2 => points: 30
3 => points: 20
4 => points: 10

所以我认为下面的代码会起作用。

$users = User::all();
$users = $users->sortByDesc(function($item){
    return $item->points()->sum('amount');
})->values();

然后从位置获取 3 个用户 - 1 到位置 + 1:

$myRank = $users->splice($position - 1, 3);

答案 2

要按键对集合进行排序,可以按键对支持数组进行排序,然后再次重新创建集合。

 $c = collect(['a' => 1, 'c' => 67, 'b' => 2]);
 $items = $c->all();
 ksort($items);

 $c = collect($items);

或者,您可以使用宏来访问后备数组。

 Collection::macro('ksort', function(){
    //macros callbacks are bound to collection so we can safely access
    // protected Collection::items
    ksort($this->items);
    
    return $this;
    //to return a new instance
    //return collect($this->items);
 });

如果您需要在代码库中的许多位置按键对集合进行排序,则最后一个解决方案可能非常有用


推荐