【问题标题】:How to properly merge multiple collections in Laravel如何在 Laravel 中正确合并多个集合
【发布时间】:2015-11-29 23:50:40
【问题描述】:

我想将多个集合合并为一个。我确实有一个解决方案,如下所示:

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

这确实有效,但在部分或全部集合不包含对象的情况下会遇到问题。我收到call to merge() on non object 的错误。

我实际上尝试创建一个包含所有集合的数组,然后遍历它们,同时检查它们的有效性,但它不起作用,我觉得它不是很优雅。

如何优雅地迭代合并多个集合的过程,同时考虑到部分或全部集合可能为空或无效?赞赏!

【问题讨论】:

    标签: php laravel laravel-4 foreach laravel-5


    【解决方案1】:

    我最终做的是分离每个步骤。杀死它的是合并链,因为部分或全部集合可能无效。

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

    【讨论】:

    • 不能链接这些很奇怪,但我可以确认这是正确的。
    • 只是更新给看到这个的人,你可以$allItems = collect();创建一个新集合。
    • 如果你合并表集合最好使用->concat($collection1) 而不是->merge($collection1) 因为两个表行具有来自不同表的相同ID,将显示与合并
    • 我们为什么不做这样的链$allItems = $collection1->merge($collection2)->merge($collection3)
    【解决方案2】:

    我有同样的问题,所以我通过以下方式解决了它:

    $clients = ClientAccount::query()->get();
    $admins = AdminAccount::query()->get();
    
    $users = collect($clients)->merge($admins)->merge($anotherCollection)->merge(...);
    

    【讨论】:

      【解决方案3】:

      我使用了->merge(),但遇到了一个小问题。所以我添加这个以防其他人面临同样的问题。 ->concat()是数据库集合合并的更好解决方案。

      $allItems = new \Illuminate\Database\Eloquent\Collection; 
      $allItems = $allItems->concat($collection1);
      $allItems = $allItems->concat($collection2);
      

      这样做的原因是在合并时他们以表的ID作为键。因此,如果两个表有两条具有相同表 id 的记录->merge() 将只添加一条记录到$allItems。但是->concat() 会添加两条记录。

      【讨论】:

      • 合并是否也适用于分页?例如我们可以做类似 $allItems->paginate(10) 的东西吗
      • @SkykidFelix 我相信是的。我发现这篇文章itsolutionstuff.com/post/…
      • 感谢它有效。有没有办法通过 'created_at' => 'DESC' 对数组进行排序
      • 比如什么时候需要获取最新的帖子?
      • @SkykidFelix 发现了这个stackoverflow.com/questions/36169847/… 希望这有用
      【解决方案4】:

      取决于您的数据,如果集合实际上为 null 或者您的 php 支持它,您可以这样做:

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

      或者你想做一个reduce:

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

      或者简单的 php reduce 没有开销

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

      【讨论】:

      • 不幸的是,这些没有考虑到部分或全部集合可能无效的事实,包括 $collection1
      【解决方案5】:

      你也可以试试:

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

      【讨论】:

      • 这不是一个合并的集合,它是一个包含四个独立集合的集合。
      【解决方案6】:

      在 Laravel 中收集不同集合的简单方法是使用 add() 函数。

      例如;让我们有 3 个表,即董事会、员工、空缺。现在,如果我们要检索员工以将他们分配为陪审团,他们必须在空缺职位所属的董事会之下。但是我们不知道哪个员工在职称的董事会下,因为可能同时有很多职位空缺。要获得每个空缺的董事会,请遍历 foreach 循环中的空缺。当您循环选择具有该董事的员工作为第一项并合并其余员工。

       $employees = null;
          if ($vacancies && $vacancies->isNotEmpty()) {
              foreach ($vacancies as $key => $vacancy) {
                  if ($employees == null) {
                      $employees = Employee::where([
                          'department_id' => $vacancy->directorate_id,
                      ])->get();
                  } else {
                      $employee = Employee::where([
                          'department_id' => $vacancy->directorate_id,
                      ])->get();
      
                      if ($employee && $employee->isNotEmpty()) {
                          foreach ($employee as $emp) {
                              $employees->add($emp);
                          }
                      }
                  }
              }
          }
      
          dd($employees);
      

      The output of dump and die

      【讨论】:

      • 其他提供的解决方案不涉及嵌套循环,而且更简单。
      【解决方案7】:

      只需使用merge

      $items  = Model::get();
      $items1 = Model::get();
      $items2 = Model::get();
      $items3 = Model::get();
      
      
      $items = $items->merge($items1);
      $items = $allItems->merge($items2);
      $items = $allItems->merge($items3);
      

      这也可以很简单的一行

      $items = $items->merge($items1)->merge($items2)->merge($items3);
      
      dd($items);
      

      它将合并您的所有收藏...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-05
        • 2017-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多