Laravel sortiert die Sammlung und dann nach Schlüssel

Lesezeit: 3 Minuten

Benutzeravatar von zarcel
zarcel

Ich mache ein Raking-System für meine Benutzer und hier ist, was ich bisher habe:

Holen Sie sich alle Benutzer und sortieren Sie sie nach Punkten – es funktioniert gut.

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

Finden Sie Ihre Position im Ranking – es funktioniert gut

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

Holen Sie sich und Benutzer über/unter mir – es funktioniert nicht. Ich bekomme zufällige Benutzer. Anscheinend ist die Sammlung nicht mehr sortiert.

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

Bitte helfen Sie mir dabei oder geben Sie einen Hinweis auf einen anderen Ansatz (geringes Gewicht für viele Datensätze)

Ich denke das Problem ist folgendes:

Wenn du anrufst User::all() du bekommst sowas:

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

Dann verwenden Sie die sortBy-Funktion, die die Sammlung neu ordnet, aber die Schlüssel nicht zurücksetzt. So kommt man am Ende auf so etwas:

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

Die Verwendung von Position -1, Position und Position +1 macht hier also keinen Sinn.

Was Sie tun können, ist die Verwendung der values() -Funktion, die die Schlüssel Ihrer Sammlung zurücksetzt:

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

Ich denke also, dass der folgende Code funktionieren würde.

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

Und dann 3 Benutzer von Position – 1 zu Position + 1 bringen:

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

  • Ich denke, Sie können die Sammlungsklasse erweitern und dann ksort für das unterstützende Array aufrufen. Sehr dreckiger Hack

    – Peter Chaula

    30. Mai 2017 um 20:33 Uhr

Benutzeravatar von Peter Chaula
Peter Chaula

Um eine Sammlung nach Schlüssel zu sortieren, können Sie das Sicherungsarray nach Schlüssel sortieren und dann die Sammlung erneut erstellen.

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

 $c = collect($items);

Oder Sie können ein Makro verwenden, um Zugriff auf das Backing-Array zu erhalten.

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

Die letzte Lösung könnte sehr nützlich sein, wenn Sie Sammlungen an vielen Stellen in Ihrer Codebasis nach Schlüsseln sortieren müssen

  • @zarcel, während es in Google erscheint, ist dies nicht nur zu Ihrem Vorteil.

    – Asche

    5. Juni 2017 um 22:50 Uhr

  • Ich stimme zu, auch wenn die Frage für den Fragesteller nicht mehr relevant ist, könnte jemand anderes die Antworten nützlich finden. Außerdem könnten in zwei Jahren neue Lösungen auftauchen.

    – Dragas

    22. November 2017 um 11:00 Uhr

  • du hast verpasst return $this; nach ksort($this->items); im Makro. =)

    – Arash

    26. November 2017 um 8:24 Uhr

  • @ArashMoosapour, das die Instanz zurückgibt, ist nicht obligatorisch, da ksort einen Verweis auf das ursprüngliche Array nimmt

    – Peter Chaula

    26. November 2017 um 10:46 Uhr

  • @ArashMoosapour Ich habe die Änderung vorgenommen, um die Sammlungsinstanz zurückzugeben. “……. ksort bei Sammlung singen, es gibt null zurück “. Sie sollten den Rückgabewert keiner Variablen zuweisen. Rufen Sie einfach ksort auf

    – Peter Chaula

    22. Februar 2018 um 5:37 Uhr

Für jede Sortierung array von keywürde ich natives PHP vorschlagen function ksort().

Sie müssen nur die Sortiermethode verwenden:

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

1444710cookie-checkLaravel sortiert die Sammlung und dann nach Schlüssel

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy