Swiftでアプリ開発を行う上で、コレクション型の理解は必須です。この記事では、Swiftの3つのコレクション型(Array、Set、Dictionary)について、初心者にもわかりやすく実例を交えて解説します。
Swiftのコレクション型とは?
コレクション型とは、複数の値をまとめて管理するためのデータ構造です。例えば、ユーザーのリストや商品の在庫、設定情報などを効率的に扱うことができます。
Swiftには主に3つのコレクション型があります。
- Array(配列):順序のある値の集まり
- Set(セット):重複しない値の集まり
- Dictionary(辞書):キーと値のペア
それぞれの特徴と使い方を詳しく見ていきましょう。
1. Array(配列):順序を保持するコレクション
Arrayは最もよく使われるコレクション型で、順序を持った値の集まりです。同じ値を複数回格納できます。
Arrayの基本的な使い方
配列の作成
// 型推論を使った作成
var fruits = ["りんご", "バナナ", "オレンジ"]
// 型を明示して作成
var numbers: [Int] = [1, 2, 3, 4, 5]
// 空の配列を作成
var emptyArray = [String]()
var anotherEmpty: [Int] = []
要素へのアクセス
配列の要素にはインデックス(添字)でアクセスします。インデックスは0から始まります。
let fruits = ["りんご", "バナナ", "オレンジ"]
print(fruits[0]) // "りんご"
print(fruits[1]) // "バナナ"
print(fruits[2]) // "オレンジ"
注意:存在しないインデックスにアクセスするとエラーになります。
配列の要素を追加する
var fruits = ["りんご", "バナナ"]
// 末尾に追加
fruits.append("オレンジ")
// 結果:["りんご", "バナナ", "オレンジ"]
// 特定の位置に挿入
fruits.insert("いちご", at: 0)
// 結果:["いちご", "りんご", "バナナ", "オレンジ"]
// 複数の要素を追加
fruits += ["ぶどう", "メロン"]
// 結果:["いちご", "りんご", "バナナ", "オレンジ", "ぶどう", "メロン"]
配列の要素を削除する
var fruits = ["りんご", "バナナ", "オレンジ", "ぶどう"]
// 特定のインデックスの要素を削除
fruits.remove(at: 1)
// 結果:["りんご", "オレンジ", "ぶどう"]
// 最後の要素を削除
fruits.removeLast()
// 結果:["りんご", "オレンジ"]
// 最初の要素を削除
fruits.removeFirst()
// 結果:["オレンジ"]
// 全ての要素を削除
fruits.removeAll()
// 結果:[]
配列の便利なプロパティとメソッド
let fruits = ["りんご", "バナナ", "オレンジ"]
// 要素数を取得
print(fruits.count) // 3
// 配列が空かどうかチェック
print(fruits.isEmpty) // false
// 最初の要素を取得(Optional型)
print(fruits.first) // Optional("りんご")
// 最後の要素を取得(Optional型)
print(fruits.last) // Optional("オレンジ")
// 特定の要素が含まれるかチェック
print(fruits.contains("バナナ")) // true
2. Set(セット):重複しない値のコレクション
Setは順序を持たず、重複した値を保持しないコレクションです。要素の存在確認が高速で、集合演算が得意です。
Setの基本的な使い方
セットの作成
// 型注釈が必要(型推論だけではSetにならない)
var colors: Set<String> = ["赤", "青", "緑"]
// 型推論を使う場合
var numbers: Set = [1, 2, 3, 4, 5]
// 重複は自動的に削除される
var duplicates: Set = [1, 2, 2, 3, 3, 3]
print(duplicates) // [1, 2, 3](順序は不定)
セットの要素を追加・削除する
var colors: Set<String> = ["赤", "青", "緑"]
// 要素を追加
colors.insert("黄色")
// 結果:["赤", "青", "緑", "黄色"]
// 要素を削除
colors.remove("青")
// 結果:["赤", "緑", "黄色"]
// 要素の存在確認
print(colors.contains("赤")) // true
print(colors.contains("紫")) // false
セット演算
Setは数学の集合演算を簡単に実行できます。
let set1: Set = [1, 2, 3, 4]
let set2: Set = [3, 4, 5, 6]
// 和集合(union):両方の要素を全て含む
print(set1.union(set2))
// 結果:[1, 2, 3, 4, 5, 6]
// 積集合(intersection):両方に含まれる要素
print(set1.intersection(set2))
// 結果:[3, 4]
// 差集合(subtracting):set1にあってset2にない要素
print(set1.subtracting(set2))
// 結果:[1, 2]
// 対称差(symmetricDifference):片方にしかない要素
print(set1.symmetricDifference(set2))
// 結果:[1, 2, 5, 6]
Setの実践例
// 重複を除きたい場合
let numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
let uniqueNumbers = Set(numbers)
print(uniqueNumbers) // [1, 2, 3, 4, 5]
// タグの管理
var articleTags: Set = ["Swift", "iOS", "プログラミング"]
articleTags.insert("開発")
articleTags.insert("Swift") // すでに存在するので追加されない
3. Dictionary(辞書):キーと値のペアを管理
Dictionaryは、キーと値のペアを格納するコレクションです。キーを使って値に高速アクセスできます。
Dictionaryの基本的な使い方
辞書の作成
// キーと値のペアで作成
var scores = ["太郎": 85, "花子": 92, "次郎": 78]
// 型を明示して作成
var ages: [String: Int] = ["太郎": 20, "花子": 22]
// 空の辞書を作成
var emptyDict = [String: Int]()
var anotherEmpty: [String: String] = [:]
値へのアクセス
辞書から値を取得すると、Optional型で返されます(キーが存在しない可能性があるため)。
let scores = ["太郎": 85, "花子": 92, "次郎": 78]
// 値を取得(Optional型)
print(scores["太郎"]) // Optional(85)
// デフォルト値を指定して取得
print(scores["太郎", default: 0]) // 85
print(scores["美咲", default: 0]) // 0
// Optional Bindingで安全に取得
if let score = scores["花子"] {
print("花子の点数は\(score)点です")
}
辞書の要素を追加・更新する
var scores = ["太郎": 85, "花子": 92]
// 新しいキーと値を追加
scores["美咲"] = 88
// 結果:["太郎": 85, "花子": 92, "美咲": 88]
// 既存のキーの値を更新
scores["太郎"] = 90
// 結果:["太郎": 90, "花子": 92, "美咲": 88]
// updateValueメソッドを使う(古い値を返す)
let oldValue = scores.updateValue(95, forKey: "花子")
print(oldValue) // Optional(92)
辞書の要素を削除する
var scores = ["太郎": 85, "花子": 92, "次郎": 78]
// nilを代入して削除
scores["次郎"] = nil
// 結果:["太郎": 85, "花子": 92]
// removeValueメソッドを使う(削除した値を返す)
let removed = scores.removeValue(forKey: "花子")
print(removed) // Optional(92)
// 全ての要素を削除
scores.removeAll()
辞書の繰り返し処理
let scores = ["太郎": 85, "花子": 92, "次郎": 78]
// キーと値を両方取得
for (name, score) in scores {
print("\(name): \(score)点")
}
// キーだけを取得
for name in scores.keys {
print("名前: \(name)")
}
// 値だけを取得
for score in scores.values {
print("点数: \(score)")
}
// キーまたは値を配列として取得
let names = Array(scores.keys)
let points = Array(scores.values)
コレクションの共通操作:高階関数
Swiftのコレクションは、便利な高階関数を使ってデータを操作できます。
map:各要素を変換する
let numbers = [1, 2, 3, 4, 5]
// 各要素を2倍にする
let doubled = numbers.map { $0 * 2 }
print(doubled) // [2, 4, 6, 8, 10]
// 文字列に変換
let strings = numbers.map { "数字: \($0)" }
print(strings) // ["数字: 1", "数字: 2", "数字: 3", "数字: 4", "数字: 5"]
filter:条件に合う要素を抽出する
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 偶数だけを抽出
let evens = numbers.filter { $0 % 2 == 0 }
print(evens) // [2, 4, 6, 8, 10]
// 5より大きい数を抽出
let greaterThanFive = numbers.filter { $0 > 5 }
print(greaterThanFive) // [6, 7, 8, 9, 10]
reduce:要素を集約する
let numbers = [1, 2, 3, 4, 5]
// 合計を計算
let sum = numbers.reduce(0, +)
print(sum) // 15
// 積を計算
let product = numbers.reduce(1, *)
print(product) // 120
// 文字列を連結
let words = ["Swift", "は", "素晴らしい"]
let sentence = words.reduce("") { $0 + $1 }
print(sentence) // "Swiftは素晴らしい"
sorted:要素をソートする
let numbers = [5, 2, 8, 1, 9]
// 昇順にソート
let ascending = numbers.sorted()
print(ascending) // [1, 2, 5, 8, 9]
// 降順にソート
let descending = numbers.sorted(by: >)
print(descending) // [9, 8, 5, 2, 1]
// カスタムソート
let fruits = ["バナナ", "りんご", "ぶどう", "いちご"]
let sorted = fruits.sorted { $0.count < $1.count }
print(sorted) // 文字数でソート
compactMap:nilを除外して変換
let strings = ["1", "2", "three", "4", "five"]
// 数値に変換できるものだけを取得
let numbers = strings.compactMap { Int($0) }
print(numbers) // [1, 2, 4]
// Optional配列からnilを除外
let optionalNumbers: [Int?] = [1, nil, 3, nil, 5]
let validNumbers = optionalNumbers.compactMap { $0 }
print(validNumbers) // [1, 3, 5]
可変性:varとletの違い
Swiftのコレクションは、var
とlet
で可変性が変わります。
varで宣言:変更可能
var mutableArray = [1, 2, 3]
mutableArray.append(4) // OK
mutableArray[0] = 10 // OK
print(mutableArray) // [10, 2, 3, 4]
letで宣言:変更不可
let immutableArray = [1, 2, 3]
// immutableArray.append(4) // エラー
// immutableArray[0] = 10 // エラー
print(immutableArray) // [1, 2, 3]
ベストプラクティス:変更する必要がない場合はlet
を使いましょう。安全性が高まり、コンパイラの最適化も効きやすくなります。
どのコレクションを使うべきか?使い分けガイド
適切なコレクションを選ぶことで、コードの効率と可読性が向上します。
コレクション | 使うべき場面 | 特徴 |
---|---|---|
Array | 順序が重要な場合<br>同じ値を複数保持したい<br>インデックスでアクセス | 順序保持<br>重複可能<br>高速なインデックスアクセス |
Set | 重複を許さない<br>要素の存在確認が頻繁<br>順序が不要<br>集合演算が必要 | 重複不可<br>順序なし<br>高速な検索<br>集合演算 |
Dictionary | キーで値を管理したい<br>設定やプロパティの管理<br>キーによる高速アクセス | キーと値のペア<br>順序なし<br>高速な検索 |
実践例での使い分け
// ユーザーのリスト(順序が重要)
var userList: [String] = ["太郎", "花子", "次郎"]
// タグの管理(重複を避けたい)
var tags: Set<String> = ["Swift", "iOS", "開発"]
// ユーザー設定(キーで管理)
var settings: [String: Bool] = [
"通知": true,
"ダークモード": false,
"自動保存": true
]
実践例:コレクションを使った実装パターン
例1:ショッピングカートの実装
// 商品の辞書(商品名: 価格)
let products = [
"りんご": 100,
"バナナ": 150,
"オレンジ": 120
]
// カートに入れた商品(配列)
var cart = ["りんご", "バナナ", "りんご"]
// 合計金額を計算
let total = cart.reduce(0) { sum, item in
sum + products[item, default: 0]
}
print("合計: \(total)円") // 350円
例2:重複チェック機能
// 登録済みのユーザー名をSetで管理
var registeredUsers: Set<String> = ["taro", "hanako", "jiro"]
func registerUser(username: String) -> Bool {
if registeredUsers.contains(username) {
print("そのユーザー名は既に使用されています")
return false
} else {
registeredUsers.insert(username)
print("登録完了しました")
return true
}
}
registerUser(username: "taro") // 既に使用されています
registerUser(username: "kenji") // 登録完了
例3:データのグループ化
// 学生の成績
let students = [
("太郎", 85),
("花子", 92),
("次郎", 78),
("美咲", 92),
("健二", 85)
]
// 点数でグループ化
var scoreGroups: [Int: [String]] = [:]
for (name, score) in students {
if scoreGroups[score] == nil {
scoreGroups[score] = []
}
scoreGroups[score]?.append(name)
}
print(scoreGroups)
// [85: ["太郎", "健二"], 92: ["花子", "美咲"], 78: ["次郎"]]
コレクションのパフォーマンス
各コレクションの操作には、計算量の違いがあります。
操作 | Array | Set | Dictionary |
---|---|---|---|
要素の追加 | O(1)* | O(1) | O(1) |
要素の検索 | O(n) | O(1) | O(1) |
要素の削除 | O(n) | O(1) | O(1) |
インデックスアクセス | O(1) | – | – |
*末尾への追加の場合。途中への挿入はO(n)
ポイント:要素の検索が頻繁な場合は、ArrayよりもSetやDictionaryが効率的です。
まとめ:Swiftのコレクションをマスターしよう
この記事では、Swiftの3つのコレクション型について詳しく解説しました。
重要ポイントの復習
- Array(配列)
- 順序を保持し、重複可能
- インデックスで要素にアクセス
- リストや順序が重要なデータに最適
- Set(セット)
- 重複を自動的に除外
- 高速な検索と集合演算
- ユニークな値の管理に最適
- Dictionary(辞書)
- キーと値のペアで管理
- キーによる高速アクセス
- 設定やマッピングに最適
- 高階関数
- map、filter、reduce、sortedなど
- 関数型プログラミングスタイル
- コードを簡潔に記述可能
コレクション型は、Swiftアプリ開発の基礎となる重要な概念です。それぞれの特徴を理解し、適切に使い分けることで、効率的で読みやすいコードが書けるようになります。
まずは基本的なArrayから始めて、徐々にSetやDictionaryも使いこなせるように練習していきましょう!