Swift: Swiftのループ:for-in、while、repeat-while
ループはコンピュータに同じ作業を繰り返させます。まるで工場の組み立てラインが止まらずに動き続けるように。このレッスンではSwiftのすべてのループタイプをいつどのように使うか、ベストプラクティスとともに学びます。
1. 学習目標
- for-inで配列、範囲、辞書を走査
- 条件が成り立つ間whileで繰り返し実行
- repeat-whileで少なくとも1回の実行を保証
- breakとcontinueでループの流れを制御
- ラベル付き文でネストされたループからの脱出
2. データアナリストの実話
(1) 課題:10万行のログを手動処理 — 指がもげそう
CharlieはECプラットフォームのデータアナリストです。毎日10万行のサーバーログをスキャンしてエラー率、応答時間、異常パターンを集計する必要があります。彼は最初、Excelに1行ずつ手動でコピー&ペーストしていました:
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はこの繰り返し作業に毎日3時間を費やし、常にエントリを見逃していました。すべてのログを反復処理する自動化ツールが必要でした。
(2) for-inループの解決策
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) 結果:3時間が3秒に
| 指標 | 手動Excel | ループ自動化 |
|---|---|---|
| 10万行の処理時間 | 3時間 | 3秒 |
| 見逃し・誤カウント | 5-10 | 0 |
| 再利用性 | なし | あり(ファイル名を変えるだけ) |
| Charlieの気分 | イライラ | 嬉しい |
3. for-inループ
for-inはSwiftで最も使われるループです。配列、範囲、辞書など、シーケンスを反復処理します。
graph LR
A[シーケンス] --> B[次の要素]
B --> C[本体を実行]
C --> D{さらに要素がある?}
D -->|Yes| B
D -->|No| E[続行]
| 走査対象 | 構文 | 反復ごとの値 |
|---|---|---|
| 配列 | for item in array |
要素 |
| 範囲 | for i in 1...5 |
インデックス値 |
| 辞書 | for (key, val) in dict |
キーと値のタプル |
| 文字列 | for char in string |
Character |
| インデックス付き配列 | for (i, item) in array.enumerated() |
(インデックス, 要素) タプル |
(1) 配列と範囲の走査
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) 辞書の走査
SWIFT
let scores = ["Alice": 95, "Bob": 82, "Charlie": 78]
for (name, score) in scores {
print("\(name): \(score)")
}
▶ サンプル: 月間平均気温の計算
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")
出力:
TEXT 📖 参照専用Total: 234.1 C Average: 19.5 C
4. whileとrepeat-while
whileは条件がtrueの間実行を繰り返します——正確な反復回数がわからない場合に最適です。repeat-whileは少なくとも1回の実行を保証します。
graph TB
subgraph "while"
A[条件チェック] -->|true| B[本体を実行]
B --> A
A -->|false| C[終了]
end
subgraph "repeat-while"
D[本体を実行] --> E[条件チェック]
E -->|true| D
E -->|false| F[終了]
end
| タイプ | チェックタイミング | 最小実行回数 | 使用場面 |
|---|---|---|---|
| while | 本体の前 | 0 | 条件駆動、一度も実行しない可能性あり |
| repeat-while | 本体の後 | 1 | 少なくとも1回保証、例:ユーザー入力検証 |
(1) whileループ
SWIFT
var countdown = 5
while countdown > 0 {
print("\(countdown)...")
countdown -= 1
}
print("Liftoff!")
(2) repeat-whileループ
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")
▶ サンプル: 数当てゲーム
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!")
出力:
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、ラベル付き文
breakはループを即座に終了します。continueは現在の反復をスキップして次に進みます。ラベル付き文で複数のネストされたループから脱出できます。
| 文 | 効果 | ユースケース |
|---|---|---|
break |
現在のループを即座に終了 | 目的のものが見つかったら早期終了 |
continue |
現在の反復をスキップして次へ | 不要な要素を除外 |
break <ラベル> |
名前付きラベル付きループから脱出 | ネストされたル��プからの脱出 |
continue <ラベル> |
名前付きループの次の反復にスキップ | ネストループの制御フロー |
(1) breakと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) ラベル付き文
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
}
}
}
▶ サンプル: ログのフィルタリングと分析
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")
出力:
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. 完全な例:バッチログ分析ツール
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)%")
}
出力:
TEXT 📖 参照専用=== ログ分析レポート === 合計エントリ: 9 INFO: 3 | WARN: 1 | ERROR: 4 | DEBUG: 1 === エラー詳細 === 1. [ERROR] 2026-07-15 08:05:23 DB接続タイムアウト 2. [ERROR] 2026-07-15 08:15:30 ディスクI/Oエラー 3. [ERROR] 2026-07-15 08:25:10 リクエスト失敗: タイムアウト 4. [ERROR] 2026-07-15 08:40:00 接続プール枯渇 エラー率: 44.4%
❓ よくある質問
Q for-inとwhileの使い分けは?
A 反復対象がわかっている場合(配列、範囲など)はfor-inを使用します。反復回数が不明で条件駆動の場合はwhileを、少なくとも1回の実行が必要な場合はrepeat-whileを使用します。
Q enumerated()のインデックスは0から始まりますか、1からですか?
A 0から始まります。表示を1から始めたい場合は、出力時に1を足してください。
Q whileとrepeat-whileの実際の違いは?
A whileは本体を実行する前に条件をチェックします——0回実行の可能性があります。repeat-whileは本体を先に実行してからチェックします——少なくとも1回の実行が保証されます。
Q breakとcontinueの違いは?
A breakはループ全体を終了します。continueは現在の反復をスキップして次に進みます。例え:breakは映画館から出ていくこと、continueは退屈なシーンをスキップして残りを見続けること。
Q ラベル名に制限はありますか?
A ラベル名はカスタム識別子です。慣例として
outerLoopやrowLoopのような意味のある名前を使用し、コロンを付けてforやwhileの前に置きます。📖 まとめ
- for-inはSwiftで最も一般的なループで、配列、範囲、辞書などのシーケンスの走査に使用
- whileは0回実行の可能性がある条件駆動ループに適する
- repeat-whileはループ本体が少なくとも1回実行されることを保証
- breakは現在のループを即座に終了し、continueは現在の反復の残りをスキップ
- ラベル付き文でネストされたループの複数レベルから脱出またはスキップ可能
- enumerated()はfor-inループでインデックスと要素の両方を提供
📝 練習問題
- 初級: for-inを使って1から10まで反復処理し、各数値の2乗を出力してください(例:「2の2乗は4」)。
- 中級: whileを使って簡単なカウンターを実装:100から始めて毎回7を引き、数値が0未満になるまで各ステップの値を出力してください。
- 上級: 9x9の九九表を生成するネストループプログラムを作成してください。ラベル付き文とbreak/continueを使って出力形式を制御してください(例:5の倍数の行をスキップ)。