zarcel
Estoy creando un sistema de clasificación para mis usuarios y esto es lo que tengo hasta ahora:
Obtenga todos los usuarios y ordénelos por puntos; funciona bien.
$users = User::all();
$users = $users->sortByDesc(function($item){
return $item->points()->sum('amount');
});
Encuentra tu posición en el ranking – funciona bien
$position = 0;
foreach($users as $user){
if(Auth::user()->id == $user->id) break;
$position++;
}
Ponerme a mí y a los usuarios por encima/por debajo de mí: no funciona. Obtengo usuarios aleatorios. Parece que la colección ya no está ordenada.
$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]);
}
Por favor, ayúdenme con este o den alguna pista sobre otro enfoque (peso ligero para muchos registros)
Creo que el problema es este:
Cuando usted llama User::all()
obtienes algo como esto:
0 => points: 10
1 => points: 50
2 => points: 30
3 => points: 70
4 => points: 20
Luego usa la función sortBy, que reordena la colección, pero no restablece las claves. Entonces terminas con algo como esto:
3 => points: 70
1 => points: 50
2 => points: 30
4 => points: 20
0 => points: 10
Entonces, usar la posición -1, la posición y la posición +1 no tiene sentido aquí.
Lo que puede hacer es usar la función de valores (), que restablecerá las claves de su colección:
0 => points: 70
1 => points: 50
2 => points: 30
3 => points: 20
4 => points: 10
Así que creo que el siguiente código funcionaría.
$users = User::all();
$users = $users->sortByDesc(function($item){
return $item->points()->sum('amount');
})->values();
Y luego obtenga 3 usuarios de posiciones – 1 a posición + 1:
$myRank = $users->splice($position - 1, 3);
Pedro Chaula
Para ordenar una colección por clave, puede ordenar la matriz de respaldo por clave y luego volver a crear la colección.
$c = collect(['a' => 1, 'c' => 67, 'b' => 2]);
$items = $c->all();
ksort($items);
$c = collect($items);
O puede usar una macro para obtener acceso a la matriz de respaldo.
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);
});
La última solución podría ser muy útil si necesita ordenar colecciones por clave en muchos lugares de su base de código.
Para cualquier clasificación array
por key
sugeriría PHP nativo function
kordenar().
Solo necesita usar el método de recolección de clasificación:
$c = collect(['a' => 1, 'c' => 67, 'b' => 2]);
$c->sort();