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
Laravel sort collection and then by key
提问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
如果您需要在代码库的许多地方按键对集合进行排序,最后一个解决方案可能非常有用