Как правильно объединить несколько коллекций в Laravel

Я хочу объединить несколько коллекций в одну. У меня есть решение, которое заключается в следующем:

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

это действительно работает, но я сталкиваюсь с проблемами в случаях, когда некоторые или все коллекции не содержат объектов. Я получаю ошибку по строкам call to merge() on non object.

Я на самом деле пытался создать массив всех коллекций, а затем перебирать их, проверяя их действительность, но это не сработало, и я чувствую, что это было не очень элегантный.

Как я могу элегантно перебирать этот процесс объединения нескольких коллекций, принимая во внимание, что некоторые или все коллекции могут быть пустыми или недействительными? Ценю!

3 ответов


Я решил было отделяя каждый шаг. Это была цепочка слияния, которая убивала его, потому что некоторые или все коллекции могли быть недействительными.

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

У меня был тот же вопрос, поэтому я решил его следующим образом:

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

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

зависит от ваших данных, если коллекция фактически равна нулю или ваш php поддерживает ее, вы можете сделать:

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

или вы хотите сделать сокращение:

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

или простой php уменьшить без накладных расходов

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