Swift: حلقات Swift: for-in وwhile وrepeat-while
Loops let a computer repeat the same task, like a factory assembly line running nonstop. This lesson covers when and how to use every type of loop in Swift, with best practices.
1. What You'll Learn
- Traverse arrays, ranges, and dictionaries with for-in
- Repeat execution with while while a condition holds
- Ensure at least one execution using repeat-while
- Control loop flow with break and continue
- Break out of nested loops using labeled statements
2. A Data Analyst's Real Story
(1) Pain: Manually processing 100K log lines — fingers about to fall off
Charlie is a data analyst at an e-commerce platform. Every day he needs to scan 100,000 server log lines to tally error rates, response times, and anomaly patterns. He started by manually copying and pasting row by row into Excel:
// The pain: manual line-by-line processing
let logEntry1 = "2026-07-15 10:23:45 [ERROR] DB timeout"
let logEntry2 = "2026-07-15 10:24:01 [INFO] Request completed"
// ... 99,998 more lines to go
Charlie spent 3 hours a day on this repetitive drudgery, and he'd miss entries all the time. He needed an automated tool to iterate over all the logs.
(2) The for-in Loop Solution
let logEntries = [
"2026-07-15 10:23:45 [ERROR] DB timeout",
"2026-07-15 10:24:01 [INFO] Request completed",
"2026-07-15 10:25:30 [ERROR] Connection refused"
]
var errorCount = 0
for entry in logEntries {
if entry.contains("[ERROR]") {
errorCount += 1
}
}
print("Found \(errorCount) errors in log")
(3) Result: 3 hours down to 3 seconds
| Metric | Manual Excel | Loop Automation |
|---|---|---|
| Time for 100K lines | 3 hours | 3 seconds |
| Missed / wrong counts | 5-10 | 0 |
| Reusable | No | Yes (just change filename) |
| Charlie's mood | Frustrated | Happy |
3. for-in Loops
for-in is the most-used loop in Swift. It iterates over a sequence — arrays, ranges, dictionaries, and more.
graph LR
A[Sequence] --> B[Next Element]
B --> C[Execute Body]
C --> D{More Elements?}
D -->|Yes| B
D -->|No| E[Continue]
| Traverse | Syntax | Value Per Iteration |
|---|---|---|
| Array | for item in array |
Element |
| Range | for i in 1...5 |
Index value |
| Dictionary | for (key, val) in dict |
Key-value tuple |
| String | for char in string |
Character |
| Indexed array | for (i, item) in array.enumerated() |
(index, element) tuple |
(1) Traversing Arrays and Ranges
// Traverse an array
let fruits = ["apple", "banana", "orange"]
for fruit in fruits {
print("I like \(fruit)")
}
// Traverse a range
for number in 1...5 {
print("Count: \(number)")
}
// Indexed traversal
let colors = ["red", "green", "blue"]
for (index, color) in colors.enumerated() {
print("\(index + 1). \(color)")
}
(2) Traversing Dictionaries
let scores = ["Alice": 95, "Bob": 82, "Charlie": 78]
for (name, score) in scores {
print("\(name): \(score)")
}
▶ Example: Calculating Monthly Average Temperature
// ============================================
// Calculate average from temperature data using for-in
// ============================================
let monthlyTemps = [5.2, 8.1, 12.5, 18.3, 24.1, 30.2,
32.0, 31.5, 27.8, 21.3, 14.2, 8.9]
var total = 0.0
for temp in monthlyTemps {
total += temp
}
let average = total / Double(monthlyTemps.count)
print("Total: \(total) C")
print("Average: \(String(format: "%.1f", average)) C")
Output:
TEXT 📖 للعرض فقطTotal: 234.1 C Average: 19.5 C
4. while and repeat-while
while repeats execution as long as a condition is true — great when you don't know the exact number of iterations. repeat-while guarantees at least one execution.
graph TB
subgraph "while"
A[Check Condition] -->|true| B[Execute Body]
B --> A
A -->|false| C[Exit]
end
subgraph "repeat-while"
D[Execute Body] --> E[Check Condition]
E -->|true| D
E -->|false| F[Exit]
end
| Type | Check Timing | Min Executions | When to Use |
|---|---|---|---|
| while | Before body | 0 | Condition-driven, may never execute |
| repeat-while | After body | 1 | Guaranteed at least once, e.g. user input validation |
(1) while Loop
var countdown = 5
while countdown > 0 {
print("\(countdown)...")
countdown -= 1
}
print("Liftoff!")
(2) repeat-while Loop
var attempts = 0
var success = false
repeat {
attempts += 1
print("Attempt #\(attempts)...")
success = Int.random(in: 1...10) > 5
} while !success && attempts < 3
print(success ? "Succeeded!" : "Failed after 3 attempts")
▶ Example: Number Guessing Game
// ============================================
// Number guessing game with repeat-while
// ============================================
import Foundation
let target = Int.random(in: 1...20)
var guess = 0
var attempts = 0
print("Guess a number between 1 and 20")
repeat {
attempts += 1
guess = Int.random(in: 1...20)
print("Attempt \(attempts): guessed \(guess)")
if guess < target {
print(" Too low")
} else if guess > target {
print(" Too high")
} else {
print(" Correct!")
}
} while guess != target
print("Solved in \(attempts) attempts!")
Output:
TEXT 📖 للعرض فقطGuess a number between 1 and 20 Attempt 1: guessed 7 Too low Attempt 2: guessed 15 Too high Attempt 3: guessed 12 Correct! Solved in 3 attempts!
5. break, continue, and Labeled Statements
break exits a loop immediately. continue skips the current iteration and moves to the next. Labeled statements let you jump out of multiple nested loops.
| Statement | Effect | Use Case |
|---|---|---|
break |
Terminates the current loop immediately | Early exit when target found |
continue |
Skips current iteration, moves to next | Filter out unwanted elements |
break <label> |
Breaks out of the named labeled loop | Breaking out of nested loops |
continue <label> |
Skips to next iteration of the named loop | Nested loop control flow |
(1) break and continue
let numbers = [3, 7, 1, 9, 4, 6, 8]
// break: exit when first even number found
for num in numbers {
if num.isMultiple(of: 2) {
print("Found first even: \(num)")
break
}
}
// continue: only print odd numbers
for num in numbers {
if num.isMultiple(of: 2) {
continue
}
print("Odd: \(num)")
}
(2) Labeled Statements
// Breaking out of multiple loops with a label
outerLoop: for i in 1...5 {
for j in 1...5 {
let product = i * j
if product == 12 {
print("Found: \(i) x \(j) = \(product)")
break outerLoop
}
}
}
▶ Example: Log Filtering and Analysis
// ============================================
// Processing log data with break/continue
// ============================================
let logEntries = [
"INFO Server started",
"ERROR Database connection failed",
"DEBUG Cache hit ratio 85%",
"ERROR Timeout after 30s",
"INFO Request completed in 120ms",
"ERROR Disk space low"
]
var errorCount = 0
for entry in logEntries {
if entry.hasPrefix("DEBUG") {
continue
}
if entry.hasPrefix("ERROR") {
errorCount += 1
print("[ERROR #\(errorCount)] \(entry)")
}
if errorCount >= 5 {
print("ALERT: Too many errors!")
break
}
}
print("Processed \(logEntries.count) entries, found \(errorCount) errors")
Output:
TEXT 📖 للعرض فقط[ERROR #1] ERROR Database connection failed [ERROR #2] ERROR Timeout after 30s [ERROR #3] ERROR Disk space low Processed 6 entries, found 3 errors
6. Full Example: Batch Log Analysis Tool
// ============================================
// Log analysis tool
// Combining for-in / while / break / continue
// ============================================
import Foundation
let logs = [
"[INFO] 2026-07-15 08:00:00 Server started",
"[ERROR] 2026-07-15 08:05:23 DB connection timeout",
"[INFO] 2026-07-15 08:10:45 Cache warmed up",
"[ERROR] 2026-07-15 08:15:30 Disk I/O error",
"[WARN] 2026-07-15 08:20:00 Memory usage 85%",
"[ERROR] 2026-07-15 08:25:10 Request failed: timeout",
"[INFO] 2026-07-15 08:30:00 Health check OK",
"[DEBUG] 2026-07-15 08:35:00 Query plan: index scan",
"[ERROR] 2026-07-15 08:40:00 Connection pool exhausted"
]
var stats = (info: 0, warn: 0, error: 0, debug: 0)
var errorLines: [String] = []
for entry in logs {
if entry.hasPrefix("[DEBUG]") {
stats.debug += 1
continue
}
if entry.hasPrefix("[ERROR]") {
stats.error += 1
errorLines.append(entry)
} else if entry.hasPrefix("[WARN]") {
stats.warn += 1
} else if entry.hasPrefix("[INFO]") {
stats.info += 1
}
}
print("=== Log Analysis Report ===")
print("Total entries: \(logs.count)")
print("INFO: \(stats.info) | WARN: \(stats.warn) | ERROR: \(stats.error) | DEBUG: \(stats.debug)")
if stats.error > 0 {
print("\n=== Error Details ===")
var i = 0
while i < errorLines.count {
print("\(i + 1). \(errorLines[i])")
i += 1
}
print("\nError rate: \(Double(stats.error) / Double(logs.count) * 100)%")
}
Output:
TEXT 📖 للعرض فقط=== Log Analysis Report === Total entries: 9 INFO: 3 | WARN: 1 | ERROR: 4 | DEBUG: 1 === Error Details === 1. [ERROR] 2026-07-15 08:05:23 DB connection timeout 2. [ERROR] 2026-07-15 08:15:30 Disk I/O error 3. [ERROR] 2026-07-15 08:25:10 Request failed: timeout 4. [ERROR] 2026-07-15 08:40:00 Connection pool exhausted Error rate: 44.4%
❓ FAQ
outerLoop or rowLoop, followed by a colon, placed before the for or while.📖 Summary
- for-in is Swift's most common loop, used to traverse arrays, ranges, dictionaries, and other sequences
- while suits condition-driven loops that may execute zero times
- repeat-while guarantees the loop body executes at least once
- break immediately exits the current loop; continue skips the rest of the current iteration
- Labeled statements let you break out of or skip multiple levels of nested loops
- enumerated() provides both index and element in a for-in loop
📝 Exercises
- Beginner: Use for-in to iterate over 1 through 10 and print the square of each number (e.g. "The square of 2 is 4").
- Intermediate: Use while to implement a simple counter: start from 100 and subtract 7 each time, printing each step's value until the number is less than 0.
- Challenge: Write a nested loop program that generates a 9x9 multiplication table. Use labeled statements and break/continue to control output formatting (e.g. skip rows for multiples of 5).