Swift: Swiftのループ:for-in、while、repeat-while

ループはコンピュータに同じ作業を繰り返させます。まるで工場の組み立てラインが止まらずに動き続けるように。このレッスンではSwiftのすべてのループタイプをいつどのように使うか、ベストプラクティスとともに学びます。

1. 学習目標


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で最も使われるループです。配列、範囲、辞書など、シーケンスを反復処理します。

100%
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回の実行を保証します。

100%
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 ラベル名はカスタム識別子です。慣例としてouterLooprowLoopのような意味のある名前を使用し、コロンを付けてforwhileの前に置きます。

📖 まとめ


📝 練習問題

  1. 初級: for-inを使って1から10まで反復処理し、各数値の2乗を出力してください(例:「2の2乗は4」)。
  2. 中級: whileを使って簡単なカウンターを実装:100から始めて毎回7を引き、数値が0未満になるまで各ステップの値を出力してください。
  3. 上級: 9x9の九九表を生成するネストループプログラムを作成してください。ラベル付き文とbreak/continueを使って出力形式を制御してください(例:5の倍数の行をスキップ)。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%