web-dev-qa-db-fra.com

Comment fusionner correctement plusieurs collections dans Laravel

Je souhaite fusionner plusieurs collections en une seule. J'ai une solution, qui est la suivante:

$allItems = $collection1->merge($collection2)
                        ->merge($collection3)
                        ->merge($collection4)
                        ->merge($collection5);

Cela fonctionne réellement, mais je rencontre des problèmes dans les cas où certaines ou toutes les collections ne contiennent aucun objet. J'obtiens une erreur dans le sens de call to merge() on non object.

J'ai en fait essayé de créer un tableau de toutes les collections, puis de les parcourir, tout en vérifiant leur validité, mais cela n'a pas fonctionné et je pense que ce n'était pas très élégant.

Comment puis-je répéter avec élégance ce processus de fusion de plusieurs collections, tout en tenant compte du fait que certaines ou toutes les collections peuvent être vides ou invalides? Apprécié!

18
Marcel

J'ai fini par séparer chaque étape. C'était le chaînage de fusion qui le tuait, car certaines ou toutes les collections pouvaient être invalides.

$allItems = new \Illuminate\Database\Eloquent\Collection; //Create empty collection which we know has the merge() method
$allItems = $allItems->merge($collection1);
$allItems = $allItems->merge($collection2);
$allItems = $allItems->merge($collection3);
$allItems = $allItems->merge($collection4);
28
Marcel

J'avais la même question, donc je l'ai résolue de la manière suivante:

$clients = ClientAccount::query()->get();
$admins = AdminAccount::query()->get();

$users = collect($clients)->merge($admins)->merge($anotherCollection)->merge(...);
4
Leonid Dashko

dépendent de vos données, si la collecte est réellement nulle ou si votre php le supporte, vous pouvez le faire:

    $allItems = $collection1->merge($collection2 ?: collect())
                    ->merge($collection3 ?: collect())
                    ->merge($collection4 ?: collect())
                    ->merge($collection5 ?: collect());

ou vous voulez faire une réduction:

    $allItems = collect([$collection2, $collection3, $collection4])->reduce(function($arr, $item) {
        if (empty($item) || $item->isEmpty())
            return $arr;
        return $arr->merge($item);
    }, $collection1);

ou php ordinaire réduire sans frais généraux

    $allItems = array_reduce([
        $collection2,
        $collection3,
        $collection4
    ], function($arr, $item) {
        if (empty($item) || $item->isEmpty())
            return $arr;
        return $arr->merge($item);
    }, $collection1);
1
wayne

Vous pouvez également essayer:

$allItems = collect([
  'collection_1_key' => $collection_1,
  'collection_2_key' => $collection_2,
  'collection_3_key' => $collection_3,
  'collection_4_key' => $collection_4,
]);
0
hawx