Eloquent 集合:each 与 foreach
可能不是 Eloquent 集合特有的问题,但在使用它们时它只是让我感到震惊.让我们假设我们有一个 $collection
对象,它是 IlluminateSupportCollection
的一个实例.
Might not be a question specific to Eloquent collections, but it just hit me while working with them. Let's just assume we have a $collection
object which is an instance of IlluminateSupportCollection
.
现在,如果我们想要迭代它,使用带有闭包的 each()
与使用常规的 foreach
的优缺点是什么.有吗?
Now if we want to iterate over it, what are the pros and cons of using each()
with a closure versus a regular foreach
. Are there any?
foreach ($collection as $item) {
// Some code
}
对比
$collection->each(function ($item) {
// Some code
});
推荐答案
foreach
语句应该用作一种循环遍历集合并对其执行某种逻辑的方法.如果其中的内容影响程序中的其他内容,则使用此循环.
A foreach
statement should be used as a sort of a way to cycle through a collection and perform some sort of logic on it. If what is in it effects other things in the program, then use this loop.
.each
方法使用 array_map
循环遍历集合中的每个对象并对每个对象执行闭包.然后它返回结果数组.这就是关键!如果您想以某种方式更改集合,则应使用 .each
.也许它是一系列汽车,而您想要使模型大写或小写.您只需将一个闭包传递给 .each
方法,该方法接受对象并在每个 Car 对象的模型上调用 strtoupper()
.然后它返回带有所做更改的集合.
The .each
method uses array_map
to cycle through each of the objects in the collection and perform a closure on each one. It then returns the resulting array. That is the key! .each
should be used if you want to change the collection in some way. Maybe it's an array of cars and you want to make the model upper case or lower case. You would just pass a closure to the .each
method that takes the object and calls strtoupper()
on the model of each Car object. It then returns the collection with the changes that have been made.
故事的精神是这样的:使用.each
方法以某种方式改变数组中的每一项;使用 foreach
循环来使用每个对象来影响程序的其他部分(使用一些逻辑语句).
Morale of the story is this: use the .each
method to change each item in the array in some way; use the foreach
loop to use each object to affect some other part of the program (using some logic statement).
正如下面所说的那样雄辩地(看看我在那里做了什么?),上面的答案有点偏离.使用 array_map
的 .each
方法实际上从未使用过 array_map
调用的输出.因此,由 array_map
创建的新数组不会保存在 Collection
中.要更改它,最好使用 .map
方法,该方法也存在于 Collection
对象中.
As stated so Eloquently (see what I did there?) below, the above answer is slightly off. The .each
method using array_map
never actually used the output from the array_map
call. So, the new array created by array_map
would not be saved on the Collection
. To change it, you're better off using the .map
method, which also exists on a Collection
object.
使用 foreach
语句来迭代它们中的每一个更有意义,因为除非您确保使用 use<,否则您将无法访问闭包之外的变量/code> 语句,这对我来说似乎很尴尬.
Using a foreach
statement to iterate over each of them makes a bit more sense because you won't be able to access variables outside the Closure unless you make sure to use a use
statement, which seems awkward to me.
上面的回答原来写的时候的实现可以是在此处找到.
The implementation when the above answer was originally written can be found here.
他们在下面谈论的新 .each
不再使用 array_map
.它只是遍历集合中的每个项目并调用传入的 $callback
,将项目及其在数组中的键传递给它.在功能上,它似乎工作相同.我相信在阅读代码时使用 foreach
循环会更有意义.但是,我看到了使用 .each
的好处,因为它允许您将方法链接在一起,如果您喜欢的话.如果您的业务逻辑要求您能够这样做,它还允许您从回调中返回 false 以提前离开循环.
The new .each
that they are talking about below no longer uses array_map
. It simply iterates through each item in the collection and calls the passed in $callback
, passing it the item and its key in the array. Functionally, it seems to work the same. I believe using a foreach
loop would make more sense when reading the code. However, I see the benefits of using .each
because it allows you to chain methods together if that tickles your fancy. It also allows you to return false from the callback to leave the loop early if your business logic demands you to be able to.
有关新实现的更多信息,请查看 源代码.
For more info on the new implementation, check out the source code.
相关文章