Chapter 59: Swift Nested Loops
1. What is a nested loop? (very clear definition)
A nested loop means one loop inside another loop.
The inner loop runs completely for every single iteration of the outer loop.
Analogy that almost everyone understands:
Think of a calendar:
- Outer loop = months (12 times)
- Inner loop = days in that month (28–31 times)
For each month, you go through every day → total iterations = sum of days in each month.
In code terms:
|
0 1 2 3 4 5 6 7 8 9 10 |
for outer in something { // runs 5 times for inner in somethingElse { // runs 3 times for EACH outer iteration print("outer:\(outer), inner:\(inner)") } } |
Total prints: 5 × 3 = 15 times
2. The classic first example – multiplication table
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
print("Multiplication Table (1 to 10)") print("-----------------------------") for row in 1...10 { var line = "" for column in 1...10 { let product = row * column line += String(format: "%4d", product) + " " } print(line) } |
Output (partial):
|
0 1 2 3 4 5 6 7 8 9 10 11 |
Multiplication Table (1 to 10) ----------------------------- 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 ... |
Why nested loops are natural here:
- Outer loop = rows (which number we are multiplying)
- Inner loop = columns (1 × row, 2 × row, 3 × row, …)
3. Real-life example 1 – Tic-tac-toe board (2D grid)
|
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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
var board = [ [" ", " ", " "], [" ", " ", " "], [" ", " ", " "] ] // Place some moves board[0][0] = "X" board[1][1] = "O" board[2][2] = "X" // Print the board nicely print(" 0 1 2") print(" -------") for rowIndex in 0..<board.count { print("\(rowIndex)|", terminator: "") for colIndex in 0..<board[rowIndex].count { let cell = board[rowIndex][colIndex] print(" \(cell) ", terminator: "") if colIndex < board[rowIndex].count - 1 { print("|", terminator: "") } } print() if rowIndex < board.count - 1 { print(" -------") } } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
0 1 2 ------- 0| X | | ------- 1| | O | ------- 2| | | X |
Key learning points:
- Outer loop = rows
- Inner loop = columns inside each row
- We use two indices: rowIndex and colIndex
4. Real-life example 2 – Seating arrangement / table plan
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
let tables = [ ["Rahul", "Priya", "Aarav"], ["Sneha", "Karan", "Meera", "Vikram"], ["Ananya", "Rohan"] ] print("Wedding Table Seating") print("=====================") for tableNumber in 0..<tables.count { print("Table \(tableNumber + 1):") for (seat, guest) in tables[tableNumber].enumerated() { print(" Seat \(seat + 1): \(guest)") } print() } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Wedding Table Seating ===================== Table 1: Seat 1: Rahul Seat 2: Priya Seat 3: Aarav Table 2: Seat 1: Sneha Seat 2: Karan Seat 3: Meera Seat 4: Vikram Table 3: Seat 1: Ananya Seat 2: Rohan |
Typical pattern:
- Outer loop = tables / groups / categories
- Inner loop = people / items / sub-items inside each group
5. Real-life example 3 – Search / filter in 2D data
|
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 |
let students = [ ["Rahul", "A", 92], ["Priya", "A", 98], ["Aarav", "B", 85], ["Sneha", "A+", 95], ["Karan", "C", 68] ] print("Students who scored 90+:") for student in students { let name = student[0] as! String let grade = student[1] as! String let marks = student[2] as! Int if marks >= 90 { print(" • \(name) – \(grade) (\(marks)%)") } } |
Output:
|
0 1 2 3 4 5 6 7 8 |
Students who scored 90+: • Priya – A (98%) • Sneha – A+ (95%) |
6. Real-life example 4 – Pattern printing (great for understanding nesting)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
let size = 5 for row in 1...size { for _ in 1...row { print("*", terminator: "") } print() } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 |
* ** *** **** ***** |
Reverse pattern:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
for row in 1...size { // spaces first for _ in 1...(size - row) { print(" ", terminator: "") } // stars for _ in 1...row { print("*", terminator: "") } print() } |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 |
* ** *** **** ***** |
7. Very Common Beginner Mistakes & How to Avoid Them
| Mistake | Wrong / Dangerous code | Correct / Better habit | Why? |
|---|---|---|---|
| Modifying outer collection inside inner loop | for row in grid { for cell in row { grid.append(…) } } | Build new collection or use indices | Collection mutated while being iterated – crash |
| Forgetting to reset inner counter | for i in 1…5 { for j in 1…5 { print(i,j) } } (but j not reset) | Each inner loop is independent | Inner loop resets automatically |
| Using wrong index range | for i in 0…rows { … } | for i in 0..<rows { … } | 0…rows.count tries to access out-of-bounds |
| Deep nesting (pyramid of doom) | 5+ levels of nested for/if | Extract to functions or flatten logic | Code becomes unreadable & hard to debug |
| Assuming all rows have same length | matrix[row][col] without check | if col < matrix[row].count { … } | Rows can have different lengths |
8. Quick Reference – Most Used Nested Loop Patterns
| Goal | Typical nested loop structure | Real-life feeling / use-case |
|---|---|---|
| Print 2D grid / table | for row in rows { for col in columns { … } } | Chessboard, calendar, spreadsheet view |
| Process rows & columns independently | for row in matrix { for cell in row { … } } | Matrix math, image processing, game board |
| Numbered list inside groups | for group in groups { for (i, item) in group.enumerated() { … } } | Seating plan, grouped tasks, multi-team leaderboard |
| Pattern printing (stars, numbers, shapes) | for row in 1…n { for col in 1…row { print(“*”) } } | Understanding loops, interview questions |
| Search / filter in 2D data | for row in data { for item in row { if condition { … } } } | Find all matching cells, count occurrences |
9. Small Practice – Try these
- Mini multiplication table (5×5) Print 1×1 to 5×5 using nested for
- Right-aligned triangle of stars For size = 5, print:
|
0 1 2 3 4 5 6 7 8 9 10 |
* ** *** **** ***** |
- Print a 4×6 grid of coordinates Output should look like:
|
0 1 2 3 4 5 6 7 8 9 |
(0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (1,0) (1,1) (1,2) (1,3) (1,4) (1,5) (2,0) (2,1) (2,2) (2,3) (2,4) (2,5) (3,0) (3,1) (3,2) (3,3) (3,4) (3,5) |
Paste your code here if you want feedback or want to see cleaner / more elegant versions!
What would you like to explore next?
- Nested loops with break and continue
- Nested loops in SwiftUI (ForEach inside ForEach)
- How to flatten nested loops into functional style (flatMap, map + joined)
- Multidimensional arrays + nested loops (2D tables, grids…)
- Or move to another topic (dictionaries, sets, optionals, switch…)
Just tell me — we’ll continue in the same clear, patient, detailed style 😊
