As documented in both Array and Dictionary forEach(_:)
Instance methods:
Calls the given closure on each element in the sequence in the same order as a for-in loop.
Nevertheless, adapted from Sequence Overview:
A sequence is a list of values that you can step through one at a time. The most common way to iterate over the elements of a sequence is to use a for-in loop.
Implying that iterating sequence by forEach(_:)
or for in
:
let closedRange = 1...3 for element in closedRange { print(element) } // 1 2 3 closedRange.forEach { print($0) } // 1 2 3
Or (Array):
let array = [1, 2, 3] for element in array { print(element) } // 1 2 3 array.forEach { print($0) } // 1 2 3
Would gives the same output.
Why forEach(_:)
even exist? i.e what is the benefit of using it instead of the for in
loop? would they be the same from performance point view?
As an assumption, it could be a syntactic sugar especially when working with functional programming.
forEach loop: The forEach() method is also used to loop through arrays, but it uses a function differently than the classic “for loop”. It passes a callback function for each element of an array together with the below parameters: Current Value (required): The value of the current array element.
foreach is useful when iterating all of the items in a collection. for is useful when iterating overall or a subset of items. The foreach iteration variable which provides each collection item, is READ-ONLY, so we can't modify the items as they are iterated.
The every() function is a good alternative to forEach, let us see an example with a test implementation, and then let's return out of the every() function when a certain condition meet.
There is no performance benefit offered by forEach
. In fact, if you look at the source code, the forEach
function actually simply performing for
-in
. For release builds, the performance overhead of this function over simply using for
-in
yourself is immaterial, though for debug builds, it results in an observable performance impact.
The main advantage of forEach
is realized when you are doing functional programming, you can add it to a chain of functional calls, without having to save the prior result into a separate variable that you'd need if you used for
-in
syntax. So, instead of:
let objects = array.map { ... } .filter { ... } for object in objects { ... }
You can instead stay within functional programming patterns:
array.map { ... } .filter { ... } .forEach { ... }
The result is functional code that is more concise with less syntactic noise.
FWIW, the documentation for Array, Dictionary, and Sequence all remind us of the limitations introduced by forEach
, namely:
You cannot use a
break
orcontinue
statement to exit the current call of thebody
closure or skip subsequent calls.Using the
return
statement in thebody
closure will exit only from the current call tobody
, not from any outer scope, and won't skip subsequent calls.
I recently ran across a use case where using forEach
was preferable in a tangible way to for in
. Let's say you want to remove all sublayers from a layer. A statement such as the below doesn't work as you need to unwrap the [CALayer]
for layer in self.videoContainerView.layer.sublayers!
If sublayers are nil, you will get a crash. This forces you to check to see if there are sublayers first. However, a forEach
makes this much simpler as in the following:
self.videoContainerView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With