Swift: Swift Loops: for-in, while, and 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


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:

SWIFT
// 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

SWIFT
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.

100%
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

SWIFT
// 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

SWIFT
let scores = ["Alice": 95, "Bob": 82, "Charlie": 78]
for (name, score) in scores {
    print("\(name): \(score)")
}

▶ Example: Calculating Monthly Average Temperature

SWIFT
// ============================================
// 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 📖 Display only
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.

100%
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

SWIFT
var countdown = 5
while countdown > 0 {
    print("\(countdown)...")
    countdown -= 1
}
print("Liftoff!")

(2) repeat-while Loop

SWIFT
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

SWIFT
// ============================================
// 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 📖 Display only
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

SWIFT
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

SWIFT
// 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

SWIFT
// ============================================
// 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 📖 Display only
[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

SWIFT
// ============================================
// 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 📖 Display only
=== 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

Q How do I choose between for-in and while?
A Use for-in when you know what you're iterating over (arrays, ranges etc.). Use while when the number of iterations is unknown and condition-driven. Use repeat-while when you need at least one execution.
Q Does the index from enumerated() start at 0 or 1?
A Starts at 0. If you want to display starting from 1, just add 1 when printing.
Q What's the actual difference between while and repeat-while?
A while checks the condition before executing the body — it may execute zero times. repeat-while executes the body first, then checks — guaranteed at least one execution.
Q What's the difference between break and continue?
A break terminates the entire loop. continue skips the current iteration and moves to the next. Analogy: break is walking out of the cinema; continue is skipping a boring scene but staying to watch the rest.
Q Are there any restrictions on label names?
A Label names are custom identifiers. Conventionally use meaningful names like outerLoop or rowLoop, followed by a colon, placed before the for or while.

📖 Summary


📝 Exercises

  1. 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").
  2. 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.
  3. 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).
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏