我正在尝试合并多个集合,但由于任何原因我无法执行此操作。我的代码看起来像这样:
$restaurant = \App\Restaurant::find(3);
$images = $restaurant->images;
$userimages = $restaurant->userimages;
$hours = $restaurant->hours;
$collectionMerge1 = $images->merge($userimages)->merge($hours);
$collectionMerge2 = $restaurant->userimages->merge($hours)->merge($images);
$collectionMerge3 = collect(array_merge($images->all(), $userimages->all(), $hours->all()));
唯一有效的合并是最后一个。前面的内容并未显示集合中包含的所有项目。为什么是这样?我究竟做错了什么? 如果您查看图片,您会发现合并 1 和 2 中缺少对象。我尝试了多种方法来做到这一点,但只适用于最后一种。也许合并方法的键有问题?
总的来说,我觉得合并有很多陷阱,我相信大多数问题都是在您尝试使用
concat
将键值数组合并在一起或 merge()
索引数组时出现的。
此问题的解决方案是使用
concat
而不是使用 merge()
方法。 Concat
将另一个集合或数组添加到当前集合的末尾。因此,在索引数组上使用时不会发生冲突。
只需使用
Laravel
收集方法,如下所示。
$images = $images->concat($userimages)->concat($hours);
这已经很旧了,但对于后代来说。
让我给你举个简单的例子 - 比你的收藏更容易理解。
它将在底部应用到您的。
当初始 Eloquent 集合时,您所描述的情况会发生:$cars - 与以下集合之一具有相同的 id 键。
例如$cars 与 $bikes 中的元素具有相同的 id
如果你这样使用它:
$vehicles = $cars->merge($bikes);
...你会被覆盖。
当您也以这种方式使用它时,您会得到相同的覆盖:
$vehicles = $cars->merge($buses)->merge($bikes);
无论如何,合道时自行车放在哪里。
有一个简单的解决方法:
$vehicles = collect();
$vehicles = $vehicles->merge($buses)->merge($bikes)->merge($cars);
在这种情况下,由于您的初始集合没有元素,因此它不能与任何后续集合冲突,并且您不会被覆盖。
它应该适用于任何合并顺序,只要空集合先出现。
在您的示例中,而不是:
$collectionMerge1 = $images->merge($userimages)->merge($hours);
你应该这样做:
$collectionMerge1 = collect();
$collectionMerge1 = $collectionMerge1->merge($images)->merge($userimages)->merge($hours);
由于空集合是用于合并的基础集合,因此它不会与任何后续集合混淆,因为它没有元素。
鉴于您的每个值实际上代表一个适当的集合(通过关系建立),您应该使用
push
而不是 merge
。这是因为当密钥对已经匹配时,merge
实际上会覆盖某些元素:
$aggregates = collect([]);
$aggregates ->push($images)->push($userImages)->push($hours);
dd($aggregates ); //as expected