Chapter 60: Swift For-Each Loop
1. What is forEach?
forEach is a method that belongs to all collection types (Array, Set, Dictionary, String, etc.).
It is a very short way to say:
“For every element in this collection, please run this piece of code once.”
Basic form:
|
0 1 2 3 4 5 6 7 8 |
array.forEach { element in // do something with element } |
Or even shorter (using implicit $0):
|
0 1 2 3 4 5 6 7 8 |
array.forEach { print("I see \($0)") } |
2. The most important differences compared to for-in
| Aspect | for item in array { … } | array.forEach { … } | Which one most developers prefer in 2025? |
|---|---|---|---|
| Syntax | keyword for … in … | method call .forEach { … } | both — depends on context |
| Can use break / continue | Yes | No — cannot break or continue | for-in when you need to break |
| Can return from the surrounding function | Yes | No — cannot return early | for-in when you need early exit |
| Looks more functional / chainable | No | Yes — looks good with .map, .filter, etc. | forEach when chaining |
| Reads like a sentence | “For each item in array do…” | “Array, please for each do…” | personal taste |
| Performance | basically same | basically same | no real difference |
| Mutating the collection while looping | Allowed (but dangerous) | Allowed (but dangerous) | avoid both — use indices or new collection |
Most important decision rule you will use every day:
- If you need break, continue, or early return → use for-in
- If you just want to do something simple with every item → forEach is often cleaner
- If you are chaining operations → forEach fits better in functional style
3. Very first examples – feel the difference
Example A – Simple printing
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
let fruits = ["Mango", "Banana", "Apple", "Orange"] // Style 1: classic for-in for fruit in fruits { print("→ I like \(fruit)") } // Style 2: forEach (very common alternative) fruits.forEach { fruit in print("→ I like \(fruit)") } // Style 3: forEach with implicit $0 (short & popular) fruits.forEach { print("→ I like \($0)") } |
All three give exactly the same output.
Example B – With index (very frequent pattern)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
let tasks = ["Study Swift", "Buy groceries", "Call mom", "Gym"] // Classic for-in with enumerated() for (index, task) in tasks.enumerated() { print("\(index + 1). \(task)") } // Same thing with forEach tasks.enumerated().forEach { index, task in print("\(index + 1). \(task)") } // Even shorter tasks.enumerated().forEach { print("\($0.offset + 1). \($0.element)") } |
4. Real-life examples – code you will actually write
Example 1 – Logging / debugging (very common)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let recentSearches = [ "Swift forEach", "Swift arrays", "String interpolation", "SwiftUI List" ] print("Recent searches:") recentSearches.forEach { query in print(" • \(query)") } |
Example 2 – Update UI elements (very common in UIKit & SwiftUI)
|
0 1 2 3 4 5 6 7 8 9 10 11 |
let labels = [label1, label2, label3, label4] labels.forEach { label in label.textColor = .systemBlue label.font = .systemFont(ofSize: 16, weight: .medium) } |
Example 3 – Send analytics / log events
|
0 1 2 3 4 5 6 7 8 9 10 |
let viewedScreens = ["Home", "Profile", "Settings", "Cart"] viewedScreens.forEach { screen in Analytics.logEvent("screen_viewed", parameters: ["screen_name": screen]) } |
Example 4 – Process items with index (numbered output)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
let orderItems = [ "Wireless Earbuds", "Phone Case", "Screen Protector", "Charger" ] print("Order summary:") orderItems.enumerated().forEach { index, item in print(" Item #\(index + 1): \(item)") } |
Example 5 – Apply action to every subview (UIKit classic)
|
0 1 2 3 4 5 6 7 8 9 |
view.subviews.forEach { subview in subview.backgroundColor = .systemGray6 subview.layer.cornerRadius = 12 } |
5. Very Important Limitations of forEach
These are the reasons many experienced developers prefer for-in in some situations:
- You cannot use break or continue
|
0 1 2 3 4 5 6 7 8 9 10 |
// This is impossible with forEach for number in numbers { if number == 42 { break } // works if number.isMultiple(of: 2) { continue } } |
- You cannot return early from the function
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
func findFirstEven(_ numbers: [Int]) -> Int? { for number in numbers { if number.isMultiple(of: 2) { return number // works } } return nil } |
→ You cannot do this with forEach — it will always go through all elements.
- Harder to read when logic is complex
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// This is clearer with for-in for user in users { if user.isActive { if user.hasPremium { sendPremiumNotification(user) } else { sendBasicNotification(user) } } } |
6. When to choose forEach vs for-in
| Situation | Prefer forEach? | Prefer for-in? | Reason / guideline |
|---|---|---|---|
| Very simple action per item | Yes | — | Clean & short |
| Chaining with map/filter/reduce | Yes | — | Looks more functional |
| Just fire-and-forget (logging, analytics, UI update) | Yes | — | No need for control flow |
| Need break, continue or early return | — | Yes | for-in allows control flow |
| Complex logic inside the loop | — | Yes | Easier to read & debug |
| Need index and want numbered output | Yes (with enumerated()) | Yes | Both work well — personal taste |
7. Quick Summary – forEach cheat sheet
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Basic array.forEach { item in print(item) } // With index array.enumerated().forEach { index, item in print("\(index + 1). \(item)") } // Implicit $0 (very common) array.forEach { print($0) } // With index implicit array.enumerated().forEach { print("\($0.offset + 1). \($0.element)") } |
8. Small Practice – Try these
- Create array of 5 favorite foods → Use forEach to print “I like to eat …”
- Create array of numbers 1…10 → Use forEach + enumerated() to print “Number 1 is odd”, “Number 2 is even”…
- Create array of 6 task names → Use forEach to print “Task 1: …”, “Task 2: …” (use enumerated())
Paste your code here if you want feedback or want to see even cleaner versions!
What would you like to explore next?
- forEach vs for-in vs map vs filter — decision guide
- Looping with indices and safe bounds checking
- Nested loops (for inside for)
- Sorting arrays
- Arrays in SwiftUI (List, ForEach, @State)
- Or move to another topic (dictionaries, sets, optionals, switch…)
Just tell me — we’ll continue in the same clear, patient, detailed style 😊
