Image illustrant Laravel : Combiner et trier aléatoirement deux collections

Laravel : Combiner et trier aléatoirement deux collections

Récemment j’ai bataillé avec Laravel 4 pour parvenir à mes fins avec des relations belongsToMany et les tables de pivot qui vont avec.

Les collections résultantes de ces requêtes devaient être combinées et triées aléatoirement. J’ai volontairement simplifié les requêtes Eloquent.

$collection1 = Phoneme::find( 14 )->get();
$collection2 = Phoneme::find( 28 )->get()
$words = $collection1->merge($collection2);

Une fois le tout récupéré dans une seule collection (un objet donc) il est difficile de la trier aléatoirement comme on le ferait avec un array_rand() par exemple. Pas de problème Laravel prévoit un outil d’itération pour le tri : ->sortBy. Il ne reste plus qu’a générer une comparaison aléatoire avec rand()

$collection1 = Phoneme::find( 14 )->get();
$collection2 = Phoneme::find( 28 )->get()
$words = $collection1->merge($collection2);

$words = $words->sortBy(function($word)
{
        return rand ( -1, 1 );
});

Et le petit plus qui fait du bien c’est qu’on peut encore appliquer d’autres filtres sur une collections : ->take() par exemple pour ne prendre que les dix premiers de la collection.

$words = $words->take(10);

Et avec le chaînage çà peut devenir très concis (je ne le recommande pas pour autant afin de garder un code lisible.

Phoneme::filterByPhoneme( 14 )->get()
        ->merge( Phoneme::filterByPhoneme( 28 )->get() )
        ->sortBy( function($word) {
                return rand ( -1, 1 );
        })
        ->take( 10 )
        ->each( function($word) {
                echo $word->word . "<br>";
        });