可能不是特定于Eloquent系列的问题,但它只是在与他们合作时打击了我。我们假设我们有一个$collection
对象,它是Illuminate\Support\Collection
的一个实例。
现在,如果我们想要迭代它,那么使用each()
和闭包与常规foreach
的利弊是什么。有没有?
foreach ($collection as $item) {
// Some code
}
--- VS ---
$collection->each(function ($item) {
// Some code
});
答案 0 :(得分:49)
应该使用foreach
语句作为循环访问集合并在其上执行某种逻辑的一种方式。如果其中的内容影响程序中的其他内容,则使用此循环。
.each
方法使用array_map
循环遍历集合中的每个对象,并对每个对象执行闭包。然后它返回结果数组。这是关键!如果要以某种方式更改集合,则应使用.each
。也许这是一系列汽车,你想要制作大写或小写的模型。您只需将闭包传递给接收对象的.each
方法,并在每个Car对象的模型上调用strtoupper()
。然后它返回包含已经进行的更改的集合。
故事的故事是:使用.each
方法以某种方式更改数组中的每个项目;使用foreach
循环来使用每个对象来影响程序的其他部分(使用一些逻辑语句)。
如下所述,如此雄辩(看我在那里做了什么?),上面的答案略有偏差。使用.each
的{{1}}方法实际上从未使用array_map
调用的输出。因此,array_map
创建的新数组不会保存在array_map
上。要更改它,最好使用Collection
方法,该方法也存在于.map
对象上。
使用Collection
语句迭代每个语句会更有意义,因为除非确保使用foreach
语句,否则无法访问Closure外的变量对我来说似乎很尴尬。
最初编写上述答案时的实施可以是found here。
Laravel 5.1中的use
他们在下面讨论的新.each
不再使用.each
。它只是遍历集合中的每个项目并调用传递的array_map
,并将项目及其键传递给数组。在功能上,它似乎工作相同。我相信在阅读代码时使用$callback
循环会更有意义。但是,我看到使用foreach
的好处,因为它允许您将方法链接在一起,如果这会让您感到兴趣。它还允许您从回调中返回false,以便在您的业务逻辑要求您能够提前离开循环。
有关新实施的更多信息,请查看the source code。
答案 1 :(得分:13)
现有答案中存在许多令人困惑的错误信息。
简短的回答是:使用.each()
与foreach
迭代Laravel集合之间没有重大区别。这两种技术都可以达到相同的效果。
您是否正在修改项目与您是否使用.each()
与foreach
无关。他们都(并且不会!)允许您根据我们所谈论的项目类型修改集合中的项目。
.each()
或foreach
允许您修改对象的属性(例如$item->name = 'foo'
)。这仅仅是因为PHP对象总是像引用一样。如果您尝试使用其他对象替换整个对象(不太常见的情况),请改用.map()
。.each()
不会为您提供方法修改集合项的值。 (忽略闭包的返回值。)改为使用.map()
。如果您对性能感到疑惑,我会对Eloquent项目和字符串集合进行多次测试。在这两种情况下,使用foreach
都比.each()
快。但我们谈论的是微秒。在大多数现实场景中,与访问数据库等所需的时间相比,速度差异并不显着。
这主要取决于您的个人偏好。使用.each()
很好,因为您可以将多个操作链接在一起(例如.where(...).each(...)
)。我倾向于在我自己的代码中使用两者,这取决于每种情况看起来最干净的东西。
答案 2 :(得分:3)
与其他两个答案所说的相反,从技术上讲,execSQL()
不会更改集合中项目的值。它确实使用Collection::each()
,但它不存储该调用的结果。
如果你想修改一个集合中的每个项目(比如将它们作为Damon投射到对象中的一个评论中,那么你应该使用array_map()
。这将根据对Collection::map()
的基础调用的结果创建一个新的集合。
答案 3 :(得分:0)
使用后者更有利:each()。
您可以链接条件并编写更清晰,更具表现力的代码,例如:
$示例 - >将() - >地图() - >过滤器();
这使您更接近声明性编程,您可以告诉计算机要完成什么而不是如何完成。
一些有用的文章:
答案 4 :(得分:-2)
foreach()构造不允许您更改正在迭代的数组项的值,除非您通过引用传递数组。
foreach ($array as &$value) $value *= $value;
each()eloquent方法包装PHP array_map()函数,允许这样做。
与之前的答案状态一样,如果您有任何其他动机,则应使用foreach()。这是因为foreach()的性能比array_map()要好得多。
http://willem.stuursma.name/2010/11/22/a-detailed-look-into-array_map-and-foreach/