雄辩的收藏:每个与foreach

Nik*_*ess 44 php laravel eloquent

可能不是特定于Eloquent集合的问题,但它只是在与他们合作时打击了我.让我们假设我们有一个$collection对象是一个实例Illuminate\Support\Collection.

现在,如果我们想要迭代它,使用each()闭包与常规的优缺点是什么foreach.有没有?

foreach ($collection as $item) {
    // Some code
}

--- VS ---

$collection->each(function ($item) {
    // Some code
});
Run Code Online (Sandbox Code Playgroud)

sea*_*saw 52

一个foreach声明应作为一种通过收集的方式来循环并在其上执行某种逻辑的.如果其中的内容影响程序中的其他内容,则使用此循环.

.each方法用于array_map循环遍历集合中的每个对象,并在每个对象上执行闭包.然后它返回结果数组.这是关键!.each如果要以某种方式更改集合,应该使用它.也许这是一系列汽车,你想要制作大写或小写的模型.您只需将闭包传递给.each接受对象的方法,并调用strtoupper()每个Car对象的模型.然后它返回包含已经进行的更改的集合.

故事的士气是这样的:使用.each方法以某种方式改变数组中的每个项目; 使用foreach循环来使用每个对象来影响程序的其他部分(使用一些逻辑语句).

更新(2015年6月7日)

正如下面所说的那样雄辩(看我在那里做了什么?),上面的答案略有偏差.使用.each方法array_map从未实际使用过array_map调用的输出.因此,创建的新数组array_map不会保存在Collection.要更改它,最好使用该.map方法,该方法也存在于Collection对象上.

使用foreach语句迭代它们中的每一个都会更有意义,因为除非你确保使用一个use对我来说似乎很尴尬的语句,否则你将无法访问Closure之外的变量.

最初编写上述答案时的实现可以在这里找到.

.each 在Laravel 5.1中

.each他们在下面讨论的新内容不再使用array_map.它只是迭代集合中的每个项目并调用传入的$callback,将项目及其键传递给数组.在功能上,它似乎工作相同.我相信foreach在阅读代码时使用循环会更有意义.但是,我看到了使用的好处,.each因为它可以让你将方法链接在一起,如果这会让你觉得好奇.它还允许您从回调中返回false,以便在您的业务逻辑要求您能够提前离开循环.

有关新实现的更多信息,请查看源代码.

  • 这个答案是不正确的,并且基于对代码的误解。.each 使用 array_map() 的事实是无关紧要的,这只是一个实现细节。事实上,`.each()` 的 Laravel 代码甚至不返回 `array_map()` 的返回值,它只是被忽略了。`.each()` 和 `foreach` 对于修改值同样有用(或没用!)。详情请参阅我的回答。 (2认同)
  • 这个答案非常错误。PHP对象是可变的,每当您将它们作为变量传递时,实际上都会传递对它们的引用。因此,您可以从“ foreach”主体内,“ array_map”回调内或实际上从任何代码中对现有对象进行“突变”。那在`foreach`和`array_map`之间没有区别。您建议,通过从传递给`$ collection-> each()`的回调中返回一些内容,可以修改集合。也不是。每个方法用于调用array_map(在2015年4月之前),但未使用返回值。 (2认同)

orr*_*rrd 13

在现有答案中存在许多令人困惑的错误信息.

简答

简短的回答是:使用.each()foreach迭代Laravel集合之间没有重大区别. 两种技术都实现了相同的结果.

怎么样修改项目?

你是否修改项目与你是否使用.each()vs. 无关foreach.他们都(并且不会!)允许您根据我们谈论的项目类型修改集合中的项目.

  • 如果Collection包含对象,则修改项目:如果Collection是一组PHP对象(例如Eloquent Collection),.each()或者foreach允许您修改对象的属性(例如$item->name = 'foo').这仅仅是因为PHP对象总是像引用一样.如果您尝试使用其他对象替换整个对象(不太常见的情况),请.map()改用.
  • 如果Collection包含非对象,则修改项目:这不太常见,但如果您的Collection包含非对象(如字符串),.each()则无法修改集合项的值.(忽略闭包的返回值.).map()改为使用.

那么......我应该使用哪一个?

如果您对性能感到疑惑,我会对Eloquent项目和字符串集合进行多次测试.在这两种情况下,使用foreach速度都快于.each().但我们谈论的是微秒.在大多数现实场景中,与访问数据库等所需的时间相比,速度差异并不显着.

这主要取决于您的个人偏好.使用.each()很好,因为您可以将多个操作链接在一起(例如.where(...).each(...)).我倾向于在我自己的代码中使用两者,这取决于每种情况看起来最干净的东西.