When to use Swift For-in and ForEach

Difference between Swift For-in and For-each

Ashok Rawat
Dev Genius

--

For-in and for each are examples of control flow statements in Swift. They are different variants of for loops in Swift which are used to iterate over arrays, dictionaries, ranges, strings, and other sequences. Although most of them look similar, there are a few differences.

1. For-in

for-in loop is used to run a block of code for a certain number of times. It is used to iterate over sequences such as an array, range, string, etc.

a) for-in Loop with Array

b) for-in Loop with the dictionary
You can also iterate over a dictionary to access its key-value pairs. Each item in the dictionary is returned as a (key, value) tuple when the dictionary is iterated, and you can decompose the (key, value) tuple’s members as explicitly named constants for use within the body of the for-in loop.

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}

c) for-in Loop with where Clause
There are cases where we want to restrict the sequence only to elements that match a particular condition, for that we can add a where clause with the for-in loop to implement filters in the loop. That is if the condition in where clause returns true, the loop is executed.

let languages = ["Swift", "Java", "Objective-C", "Pyhton"]
for language in languages where language == "Swift" {
print(language)
}
Output:- Swift

d) for-in Loop with enumerated()
To access each index of the element simultaneously, we can use the instance method enumerated(). It returns a sequence of pairs that contain the index as well as the value of the element.

let continents = ["Asia", "Africa", "North America", "South America", "Antarctica", "Europe", "Australia"]for (index, value) in continents.enumerated()  {
print("Continent \(index+1):", value)
}

e) for-in Loop with Stride Function

for(i = 0; i < n; i++) {  
statements
}

The above C-Style for loops is not supported by swift, we can use Stride to archive increment/decrement of the counter variable.

for i in stride(from: 0, to: 10, by: 2) {
print(i)
}
for i in stride(from: 0, through: 10, by: 2) {
print(i)
}

f) for-in Loop with Range
A range is a series of values between two numeric intervals. We can use a for-in loop to iterate over a range.

for i in 1...3 {
print(i)
}
for index in (0...3).reversed() {
print("\(index)..")
}

To know more about the Swift range operator, Please read the post Swift Range Expressions.

g) for-in Loop with an optional pattern
If the sequence contains optional values, we can filter nil values using for case let, executing the loop for non-nil elements only.

struct User {
let name: String
let isAuthenticate: Bool?
}
let users: [User?] = [User(name: "XYZ", isAuthenticate: false), User(name: "ABC", isAuthenticate: nil)]for case let user? in users where user.isAuthenticate == false {
print(user)
}

2. For-each

forEach is a method that takes a closure and uses a for loop to iterate over all of the elements in the list and invokes the closure with each element as the argument.

@inlinable public func forEach(_ body: (Element) throws -> Void) rethrows {   
for element in self {
try body(element)
}
}

forEach calls the given closure on each element in the sequence in the same order as a for-in loop.

let numbers = [1, 2, 3, 4, 5]
numbers.forEach { num in
print(num)
}
let currencyCodes = ["United States": "USD", "India": "INR", "United Kingdom": "GBP", "South Korea": "KRW"]
currencyCodes.forEach { country, currencyCode in
print("\(country) currency code is \(currencyCode)")
}

Difference between For-in and forEach

Using the forEach method is distinct from a for-in loop in the following important ways:

1. For-in is an operator whereas for-each is a function.

2. You cannot use a break or continue statement to exit the current call of the body closure or skip subsequent calls.

Break and continue are the basic syntaxes of for loop which is used to either break the loop iteration or to continue to the next element. Since for-each is a function, trying to use break and continue inside a for-each iteration we will get compile time error.

3. Using the return statement in the body closure will exit only from the current call to body, not from any outer scope, and won’t skip subsequent calls.

Return from the scope of the for loop is not possible in the case of the for-in loop. We can use return in the for-in loop if inside a function, but it will return from the function not from the for-loop scope.

4. For-each can be used with Swift’s closures or first-class functions whereas it is not possible with the for-in loop.

func printEvenNumber(for number : Int) {
guard number % 2 == 0 else {
return
}
print(number)
}
(0...10).forEach(printEvenNumber)

Conclusion

Using a for loop gives us a much greater degree of control over an iteration while using forEach enables us to take advantage of the power of closures and first-class functions, even though we won’t be able to stop an iteration once it was started

Thanks for reading. If you have any comments, questions, or recommendations feel free to post them in the comment section below! 👇 Please share and give claps 👏👏 if you liked this post.

--

--

Mobile Engineer iOS | Swift | Objective-C | Python | React | Unity3D