php Laravel 排序集合然后按键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29645598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:29:58  来源:igfitidea点击:

Laravel sort collection and then by key

phplaravel

提问by zarcel

I am making raking system for my users and here's what I have so far:

我正在为我的用户制作耙子系统,这是我迄今为止所拥有的:

Get all users and sort them by points - it works fine.

获取所有用户并按点对它们进行排序 - 效果很好。

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

Find your position in ranking - it works fine

找到您在排名中的位置 - 效果很好

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

Get myself and users above/under me - it doesn't work. I get random users. It looks like the collection is not sorted anymore.

让我自己和用户高于/低于我 - 这是行不通的。我得到随机用户。看起来集合不再排序。

$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]);
}

Please help me with this one or give some hint on another approach(light weight for many records)

请帮我解决这个问题或给出另一种方法的提示(许多记录的重量较轻)

回答by Needpoule

I think the problem is this:

我认为问题是这样的:

When you call User::all()you get something like this:

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

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

Then you use the sortBy function, which reorder the collection, but does not reset the keys. So you end up with something like this:

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

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

So using position -1, position, and position +1 makes no sense here.

所以在这里使用位置 -1、位置和位置 +1 是没有意义的。

What you can do is using the values() function, which will reset the keys of you collection:

你可以做的是使用 values() 函数,它会重置你集合的键:

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

So I think the following code would work.

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

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

And then get 3 users from positions - 1 to position + 1:

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

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

回答by peterchaula

To sort by key, you can get the backing array then recreate the collection again.

要按键排序,您可以获取支持数组,然后再次重新创建集合。

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

 $c = collect($items);

Or you can use a macro to get access to the backing array.

或者您可以使用宏来访问支持数组。

 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);
 });

The last solution could be very useful if you are going to need to sort collections by key in many places in your code base

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

回答by Fusion

For any sorting arrayby key, I would suggest native PHP functionksort().

对于任何排序array方式key,我建议使用原生 PHP functionksort()