コレクション型(Collection Types)
最終更新日: 2021/6/27 原文: https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html
Swift は、配列、セット、辞書と呼ばれる 3 つの基本的な_コレクション型_を提供しています。配列は順序が決まったコレクションです。セットは値の重複と順序のないコレクションです。辞書はキーとバリューに関連性を持たせた順序のないコレクションです。
Collection Types(コレクション型)
Swift の配列、セット、辞書は、常に保持しているキーやバリューの型が明確です。つまり、間違った型の値を挿入することができません。これは、コレクションから取得する値の型がはっきりとわかっていることにもなります。
NOTE Swift の配列、セット、辞書は、_ジェネリックなコレクション_として実装されています。ジェネリックな型やコレクションについての詳細はGenerics(ジェネリクス)を参照ください。

コレクションの可変性(Mutability of Collections)

もし配列、セット、辞書を変数に代入した場合、作成されたコレクションは可変です。つまり、追加、削除、要素の変更など、後々そのコレクションを取り替え(または変更)できます。もし配列、セット、辞書を定数に代入した場合、コレクションは不変で、そのサイズや内容を変更できません。
NOTE コレクションの変更が必要ない場合は、不変なコレクションを作成するのが良いプラクティスです。そうすることで、コードを理解しやすくし、Swift のコンパイラもコレクションのパフォーマンスを最適化することができます。

配列(Arrays)

配列は同じ型の値を順序立ったリストの中に保持します。配列の中に同じ値を複数回入れることができます。
NOTE Array は Foundation の NSArray とスムーズにやりとりできるようにしています。Foundation と Cocoa を使った Array の使用方法に関しては、Bridging Between Array and NSArrayを参照ください

配列型の省略構文(Array Type Shorthand Syntax)

Swift の配列の型は全体で Array<Element> と書きます。Element はその配列が保持できる値の型です。簡略記法として [Element] とも書けます。この 2 つの形式は機能的に同じですが、簡略記法の方が好まれ、このガイド内でも配列の型を参照する際はこちらの形式を使います。

空の配列の作成(Creating an Empty Array)

イニシャライザの構文を使用して、ある型の空の配列を作成できます。
1
var someInts = [Int]()
2
print("someInts is of type [Int] with \(someInts.count) items.")
3
// someInts is of type [Int] with 0 items.
Copied!
someInts 変数の型は、イニシャライザから [Int] と推論されます。
他にも、コンテキスト的に型情報がわかっている場合(関数の引数や既に型が決まっている変数や定数など)は、空配列リテラルの [](空の角括弧ペア)を使用して、空の配列を作成することができます。
1
someInts.append(3)
2
// someInts Int 型の 3 を含んでいます
3
someInts = []
4
// someInts は空の配列だけど [Int] 型
Copied!

デフォルト値を使った配列の作成(Creating an Array with a Default Value)

Array は同じデフォルト値を設定した特定にサイズの配列を作成するイニシャライザも提供しています。このイニシャライザに適切な型のデフォルト値(repeating)と、その値の繰り返し回数(count)を渡します。
1
var threeDoubles = Array(repeating: 0.0, count: 3)
2
// threeDoubles は [Double] 型で、 [0.0, 0.0, 0.0] と等しい
Copied!

2つの配列の結合(Creating an Array by Adding Two Arrays Together)

加算演算子(+)を使用して、既存の型互換のある 2 つの配列を合成して、新しい配列を作成することもできます。この新しい配列の型は連結させた配列の型から推論されます:
1
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
2
// anotherThreeDoubles は [Double] 型で [2.5, 2.5, 2.5] と等しい
3
4
var sixDoubles = threeDoubles + anotherThreeDoubles
5
// sixDoubles は [Double] と推論され、 [0.0, 0.0, 0.0, 2.5, 2.5, 2.5] と等しい
Copied!

配列リテラルを使った配列の作成(Creating an Array with an Array Literal)

配列リテラルからも配列を初期化できます。これは、1 つ以上の要素を持った配列コレクションの簡略記法です。配列リテラルはカンマ区切りの角括弧([])で囲んだ値のリストです:
Array Literal
下記の例は、String を保持する shoppingList という配列を作成しています。
1
var shoppingList: [String] = ["Eggs", "Milk"]
2
// shoppingList は 2 つの 初期値で初期化されている
Copied!
shoppingList 変数は、[String] と書くことで「文字列を保持する配列」として宣言されています。この配列は値の型が String で特定されているので、String のみを保持することができます。ここで、shoppingList 配列は、配列リテラルの中で "Eggs""Milk" の 2 つの値で初期化しています。
NOTE 後の例でさらにアイテムを追加するので、shoppingList 配列は let で宣言された定数ではなく、var で変数として宣言されてます。
この例では、配列リテラルには 2 つの String を含んでいます。これは shoppingList 変数の宣言時の型(String しか含めない)に合致しているので、shoppingList に配列リテラルを代入して 2 つに初期値で初期化することができます。
Swift の型推論のおかげで、同じ型の値を含んだ配列リテラルで初期化するときに配列の型を書く必要はありません。先ほどの shoppingList の例の初期化は、より簡潔な方法で書くことができました:
1
var shoppingList = ["Eggs", "Milk"]
Copied!
配列リテラルの全ての値は同じ型なので、Swift は shoppingList 変数で使われている型は [String] が適切だと推論できます。

配列へのアクセスと変更(Accessing and Modifying an Array)

メソッドやプロパティ、subscript 構文を通して配列の要素へのアクセス、変更ができます。
配列のアイテムの数を調べるために、読み取り専用の count プロパティをチェックします。
1
print("The shopping list contains \(shoppingList.count) items.")
2
// The shopping list contains 2 items.
Copied!
Bool 型の isEmpty プロパティは、count プロパティが 0 かどうかをチェックする簡略記法です。
1
if shoppingList.isEmpty {
2
print("The shopping list is empty.")
3
} else {
4
print("The shopping list isn't empty.")
5
}
6
// The shopping list isn't empty.
Copied!
append(_:) メソッドを使用して、配列の末尾に新しいアイテムを追加することができます。
1
shoppingList.append("Flour")
2
// shoppingList は 3 つのアイテムを含んでいて、誰かがパンケーキを作っています
Copied!
加算代入演算子(+=)を使用して 1 つ以上の互換性のある型のアイテムを追加することもできます。
1
shoppingList += ["Baking Powder"]
2
// shoppingList 4 つのアイテムを含んでいます
3
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
4
// shoppingList は 7 つのアイテムを含んでいます
Copied!
subscript 構文を使用すると、配列から値を取得します。配列名のすぐ後の角括弧([])の中に、取得したい値のインデックスを渡します。
1
var firstItem = shoppingList[0]
2
// firstItem は "Eggs" と等しい
Copied!
NOTE 配列の最初のアイテムのindexは 0 であって 1 ではありません。SwiftのArrayはいつも 0 から始まるインデックス方式です。
あるインデックスの既存の値を変更したい場合も subscript 構文を使います。
1
shoppingList[0] = "Six eggs"
2
// リストの最初のアイテムは "Eggs" ではなく、 "Six eggs"
Copied!
subscript 構文を使用するとき、指定したインデックスは値の存在する範囲内でなければなりません。例えば、配列の最後に値を追加しようとして shoppingList[shoppingList.count] = "Salt" と書くと、実行時エラーになります。
ある一定範囲の値を一度に変更する場合にも、subscript 構文を使用することができます。これは置き換えたい値のセットの数と指定した置き換える範囲の長さが異なっていても可能です。次の例は "Chocolate Spread""Cheese""Butter""Bananas""Apples" に置き換えています。
1
shoppingList[4...6] = ["Bananas", "Apples"]
2
// shoppingList は 6 つのアイテムを含んでいます
Copied!
配列の特定のインデックスにアイテムを挿入したい場合、insert(_:at:) メソッドを使います。
1
shoppingList.insert("Maple Syrup", at: 0)
2
// shoppingList は 7 つのアイテムを含んでいます
3
// "Maple Syrup" は最初のアイテムです
Copied!
この例では insert(_:at:)"Maple Syrup" とインデックス 0 を指定して、ショッピングリストの先頭に新しいアイテムを挿入しています。
同様に remove(at:) を使用して配列からアイテムを削除できます。このメソッドは特定のインデックスのアイテムを削除し、削除したアイテムを返します(必要なければ戻り値は無視できます):
1
let mapleSyrup = shoppingList.remove(at: 0)
2
// インデックス 0 にあったアイテムは削除されました
3
// shoppingList は 6 つのアイテムを含んでいますが、 Maple Syrupはありません
4
// mapleSyrup 定数は削除した "Maple Syrup" 文字列と等しい
Copied!
NOTE 配列の既存の境界を超えたインデックスの値にアクセスしたり、変更したりしようとすると、実行時エラーになるでしょう。count プロパティとインデックスを比較して、インデックスが妥当かどうかをチェックしてください。配列は 0 から始まるインデックス方式なので、妥当な最大のインデックスは count - 1 です。しかし、count0 のとき(配列が空のとき)、妥当なインデックスは存在しません。
アイテムが削除された時、配列内の隙間は埋められ、インデックス 0 の値は再び "Six eggs" になります。
1
firstItem = shoppingList[0]
2
// firstItem は "Six eggs" と等しい
Copied!
配列の最後の値を削除したい場合、count プロパティを探すコストを避けるためには、remove(at:) よりも removeLast() を使います。remove(at:) と同様に removeLast() も削除したアイテムを返します:
1
let apples = shoppingList.removeLast()
2
// 最後のアイテムは削除されました
3
// shoppingList は 5 つのアイテムを含んでいますが、 apples はありません
4
// apples 定数は削除された "Apples" 文字列と等しい
Copied!

配列の繰り返し処理(Iterating Over an Array)

for-in ループを使用して配列の値全部に繰り返し処理をすることができます。
1
for item in shoppingList {
2
print(item)
3
}
4
// Six eggs
5
// Milk
6
// Flour
7
// Baking Powder
8
// Bananas
Copied!
各アイテムのインデックスが必要な場合は、enumerated() を代わりに使いましょう。enumerated() は数値のインデックスとアイテムを組み合わせたタプルを返します。数値の開始は 0 で、1 ずつ増加していきます。つまり全体を繰り返し処理すると、数値はアイテムのインデックスと一致します。繰り返し処理の中で、インデックスとアイテムのタプルを一時的な定数や変数に展開することができます。
1
for (index, value) in shoppingList.enumerated() {
2
print("Item \(index + 1): \(value)")
3
}
4
// Item 1: Six eggs
5
// Item 2: Milk
6
// Item 3: Flour
7
// Item 4: Baking Powder
8
// Item 5: Bananas
Copied!
for-in ループについては、For-In Loops(For-In ループ)を参照ください。
_セット_はコレクション内に、同じ型の値を、決まった順序と値の重複なしに保持します。アイテムの順序が重要でない場合や、アイテムに重複がないことを保証したい場合に、配列の変わりにセットを使用することができます。
Set は Foundation の NSSet とスムーズにやりとりできるようにしています。Foundation と Cocoa を使った Set の使用方法に関しては、Bridging Between Set and NSSetを参照ください

セット型のハッシュ値(Hash Values for Set Types)

セットに保存する型はハッシュ化が可能でなければなりません。つまり、その型はハッシュ値を計算する方法をセットに知らせる必要があります。ハッシュ値は、Int 型で、等価比較が可能な全てのオブジェクトで、例えば a == b の場合、a のハッシュ値は b のハッシュ値と等しくなります。
Swift の基本的な型(StringIntDoubleBool など)は、デフォルトでハッシュ化が可能で、セットや辞書のキーに使用することができます。関連値を持たない列挙型のケース(Enumerations(列挙型))もデフォルトでハッシュ化が可能です。
NOTE Swift 標準ライブラリの Hashable プロトコルに準拠することで、独自で作成した型をセットや辞書のキーに使用できます。hash(into:) メソッドの実装については、Hashableを参照ください。プロトコルの準拠については、Protocols(プロトコル)を参照ください。

セット型構文(Set Type Syntax)

セット型は Set<Element> と書きます。Element はセットが保持できる型です。セットには、配列のような簡略記法([Element])はありません。

空のセットの作成と初期化(Creating and Initializing an Empty Set)

イニシャライザの構文を使用して、ある型の空のセットを作成できます。
1
var letters = Set<Character>()
2
print("letters is of type Set<Character> with \(letters.count) items.")
3
// letters is of type Set<Character> with 0 items.
Copied!
NOTE letters 変数の型はイニシャライザの型から Set<Character> と推論されます。
他の方法として、関数の引数や型が明示されている変数や定数など型情報が既にわかっている場合は、空の配列リテラルを使用して空のセットを作成することができます。
1
letters.insert("a")
2
// letters は Character 型の値を 1 つ含んでいます
3
letters = []
4
// letters は空のセットですが、 型は Set<Character> のままです
Copied!

配列リテラルを使ったセットの作成(Creating a Set with an Array Literal)

簡略記法として、1 つ以上の値を配列リテラルを使用してセットを初期化することもできます。
下記の例は、favoriteGenres という String の値を保持するセットを作成しています。
1
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
2
// favoriteGenres は 3 つ の初期値で初期化されている
Copied!
favoriteGenres 変数は Set<String> と書くことで、「String のセット」を宣言しています。String 型の値を保持しているため、このセットには String しか保持できません。ここでは favoriteGenres セットに 3 つの String を含めた配列リテラルを使用して初期化しています。
NOTE 後の例でアイテムの追加や削除を行なっているため、favoriteGenres は定数ではなく変数で定義されています。
セットの型は配列リテラルのみからは型推論することはできず、Set を明示しなければなりません。しかし、Swift の型推論によって、1 つの型しか持たない配列リテラルの場合は、要素の型を書かなくても初期化できます。
favoriteGenres の初期化は下記のようにより簡単に書くことができました:
1
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
Copied!
配列リテラルの値は全て同じ型なので、favoriteGenres 変数は Set<String> が正しい型だと推論できます。

セットへのアクセスと変更(Accessing and Modifying a Set)

メソッドやプロパティを通してセットにアクセスしたり、変更できます。
セットのアイテムの数を調べるために、読み取り専用の count プロパティをチェックします。
1
print("I have \(favoriteGenres.count) favorite music genres.")
2
// I have 3 favorite music genres.
Copied!
Bool 型の isEmpty プロパティは、count プロパティが 0 かどうかをチェックする簡略記法です。
1
if favoriteGenres.isEmpty {
2
print("As far as music goes, I'm not picky.")
3
} else {
4
print("I have particular music preferences.")
5
}
6
// I have particular music preferences.
Copied!
insert(_:) メソッドを使用して、セットに新しいアイテムを追加することができます。
1
favoriteGenres.insert("Jazz")
2
// favoriteGenres 4 つのアイテムを含んでいます
Copied!
remove(_:) を使用してセットからアイテムを削除できます。セットにアイテムが存在した場合は削除し、削除したアイテムを返します。もし存在しなけば nil を返します。他の方法として、全アイテムを削除するには removeAll() を使います。
1
if let removedGenre = favoriteGenres.remove("Rock") {
2
print("\(removedGenre)? I'm over it.")
3
} else {
4
print("I never much cared for that.")
5
}
6
// Rock? I'm over it.
Copied!
特定のアイテムが含まれているかどうかを調べるには、contains(_:) メソッドを使用することができます。
1
if favoriteGenres.contains("Funk") {
2
print("I get up on the good foot.")
3
} else {
4
print("It's too funky in here.")
5
}
6
// It's too funky in here.
Copied!

セットの繰り返し処理(Iterating Over a Set)

for-in ループを使用してセットの要素を繰り返し処理することができます。
1
for genre in favoriteGenres {
2
print("\(genre)")
3
}
4
// Classical
5
// Jazz
6
// Hip hop
Copied!
for-in ループについては、For-In Loops(For-In ループ)を参照ください。
Swift の Set 型は決まった順序がありません。特定の順番で値を繰り返し処理したい場合、sorted() メソッドを使用すると、< 演算子を使用してソートされた配列として要素を返します。
1
for genre in favoriteGenres.sorted() {
2
print("\(genre)")
3
}
4
// Classical
5
// Hip hop
6
// Jazz
Copied!

セットの操作(Performing Set Operations)

2 つのセットの、合成、共通の要素の発見、値が全部等しいのか、いくつか等しいのか、全く違うのかの比較など、基本的なセットの操作を効率的に行うことができます。

基本的なセットの操作(Fundamental Set Operations)

下記のイラストでは、ab の 2 つのセットに対して、それぞれ操作を行い、色の付いた部分が結果(戻り値)を表しています。
Setのベン図
  • intersection(_:) は、2 つのセットの共通要素を含めた新しいセットを作成します
  • symmetricDifference(_:) は、どちらかのセットにあるものの、両方には含まれていない要素を含めた新しいセットを作成します
  • union(_:) は、両方のセットに含まれている全ての要素を含めた新しいセットを作成します
  • subtracting(_:) は、特定のセットには含まれていない要素を含めた新しいセットを作成します
1
let oddDigits: Set = [1, 3, 5, 7, 9]
2
let evenDigits: Set = [0, 2, 4, 6, 8]
3
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
4
5
oddDigits.union(evenDigits).sorted()
6
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7
oddDigits.intersection(evenDigits).sorted()
8
// []
9
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
10
// [1, 9]
11
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
12
// [1, 2, 9]
Copied!

セットの要素と等価性(Set Membership and Equality)

下記のイラストでは、abc の 3 つのセットで共有している要素の領域を表しています。 a は、b に含まれる全ての要素を含んでいるため、b の_上位集合_です。反対に、ba の_下位集合_です。bc は、共通の要素がないため、互いに_素_です。
Setのオイラー図
  • 等価演算子(==)を使用して、2 つのセットの要素が全て同じかどうかを判定できます
  • isSubset(of:) を使用してあるセットの要素が他のセットに全て含まれているかどうかを判定できます
  • isSuperset(of:) を使用してあるセットが他のセットの全ての要素を含んでいるかどうかを判定できます
  • isStrictSubset(of:)isStrictSuperset(of:) は、あるセットが他のセットの上位集合か下位集合かどうかを判定できます(等しい場合は false です)
  • isDisjoint(with:) は 2 つのセットに共通要素が全くないかどうかを判定できます
1
let houseAnimals: Set = ["🐶", "🐱"]
2
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
3
let cityAnimals: Set = ["🐦", "🐭"]
4
5
houseAnimals.isSubset(of: farmAnimals)
6
// true
7
farmAnimals.isSuperset(of: houseAnimals)
8
// true
9
farmAnimals.isDisjoint(with: cityAnimals)
10
// true
Copied!

辞書(Dictionaries)

_辞書_は、特定の型のキーと、特定の型のバリューをペアとして関連づけ、順序なしでコレクションに保持します。それぞれのアイテムは、辞書内で識別子の役割を果たす一意なキーに紐づいています。配列のアイテムとは異なり、辞書のアイテムに順序はありません。辞書は、現実に特定の単語を辞書で調べるのと同じように、識別子から値を探したいときに使います。
NOTE Dictionary は Foundation の NSDictionary とスムーズにやりとりできるようにしています。Foundation と Cocoa を使った Dictionary の使用方法に関しては、Bridging Between Dictionary and NSDictionaryを参照ください

辞書型の省略構文(Dictionary Type Shorthand Syntax)

Swift の辞書は、全体で Dictionary<Key, Value> と書きます。Key には辞書のキーとして使える値の型を、Value にはそのキーに紐づいた辞書で保持するバリューの型です。
NOTE 辞書の Key はセットの値のように、Hashable プロトコルに準拠しなければなりません。
辞書の型は、[Key: Value] と簡略記法で書くこともできます。機能的にはどちらの書き方も同じですが、簡略記法の方が好ましく、このガイド内では、辞書の型を参照する際はこちらの形式を使います。

空の辞書型の作成(Creating an Empty Dictionary)

配列と同様に、ある型の空の Dictionary をイニシャライザの構文を使用して作成できます。
1
var namesOfIntegers = [Int: String]()
2
// namesOfIntegers は空の [Int: String] 辞書
Copied!
この例では、数字を人が理解できる名前として保持するために、[Int: String] 型の空の辞書を作成しています。キーは Int 型でバリューは String 型です。
既に型情報が分かっている場合は、空の辞書リテラルを [:] と書くことができます。(角括弧([])の中にコロン(:)):
1
namesOfIntegers[16] = "sixteen"
2
// namesOfIntegers は 1 つのキーバリューペアを含んでいます
3
namesOfIntegers = [:]
4
// namesOfIntegers は再び [Int: String] の空の辞書
Copied!

辞書リテラルを使った辞書の作成(Creating a Dictionary with a Dictionary Literal)

先ほど見た配列リテラルと似たような構文の_辞書リテラル_を使った初期化もできます。辞書リテラルは、1 つ以上のキーバリューペアから Dictionary のコレクションを作成する簡略記法です。
_キーバリューペア_は、キーとバリューの組み合わせです。辞書リテラルは、それぞれのキーバリューペアのキーとバリューをコロン(:)で分けます。複数のキーバリューペアは、カンマ(,)区切りのリストを角括弧([])で囲みます:
辞書の作成
下記の例では、国際空港の名前を保持する辞書を作成します。この辞書は、3 文字の国際空港コードをキーに、空港名をバリューにしています。
1
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
Copied!
airports 辞書は、[String: String] 型と宣言され、「String 型のキーと String 型のバリューの Dictionary」を意味します。
NOTE 後の例でさらに空港を追加するため、airports 辞書は定数ではなく変数で定義されています。
airports 辞書は、2 つのキーバリューペアの辞書リテラルで初期化されています。最初のペアのキーは "YYZ"、バリューは "Toronto Pearson"、2 番目のペアのキーは "DUB"、バリューは "Dublin" です。
この辞書リテラルは、String: String 型のペアを含んでいます。このキーバリューペアは airports 変数の宣言(String 型のキーと String 型のバリューしか持つことができない辞書)と一致するので、2 つの初期値を持つ airports 辞書を初期化するために、この辞書リテラルを代入することができます。
配列と同様に、キーとバリューの型がはっきりと分かる辞書リテラルを使用して初期化している場合、型を書く必要はありません。airports の初期化は、より簡潔に書くことができました:
1
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
Copied!
キーの型も、バリューの型も全ての同じなので、Swift は airports 辞書は [String: String] が正しい型だと推論できます。

辞書へのアクセスと変更(Accessing and Modifying a Dictionary)

メソッドやプロパティ、subscript 構文を通して、辞書へのアクセス、変更ができます。
配列と同様に、Dictionary のアイテムの数を調べるために、読み取り専用の count プロパティをチェックします。
1
print("The airports dictionary contains \(airports.count) items.")
2
// The airports dictionary contains 2 items.
Copied!
Bool 型の isEmpty プロパティは、count プロパティが 0 かどうかをチェックする簡略記法です。
1
if airports.isEmpty {
2
print("The airports dictionary is empty.")
3
} else {
4
print("The airports dictionary isn't empty.")
5
}
6
// The airports dictionary isn't empty.
Copied!
subscript 構文を使用して、新しいアイテムを追加することができます。適切な型の新しいキーを subscript のインデックスに入れ、適切な型の新しいバリューを代入できます。
1
airports["LHR"] = "London"
2
// airports 辞書は 3 つのアイテムを含んでいます
Copied!
他には加算代入演算子(+=)を使用して 1 つ以上の互換性のある型のアイテムを追加できます。
1
shoppingList += ["Baking Powder"]
2
// shoppingList 4 つのアイテムを含んでいます
3
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
4
// shoppingList は 7 つのアイテムを含んでいます
Copied!
subscript 構文を使用すると、特定のキーのバリューを変更することもできます。
1
airports["LHR"] = "London Heathrow"
2
// "LHR"の値は "London Heathrow" へ変更
Copied!
別の方法として、updateValue(_:forKey:) メソッドを使用して、特定のキーのバリューの設定/更新ができます。subscript と同様に updateValue(_:forKey:) は、特定のキーのバリューがなければ新しく値を設定し、既にバリューが存在していたら更新します。subscript と違う点として、updateValue(_:forKey:) メソッドは、更新後に前の値を返します。こうすることで、更新が実際に起きたかどうかが確認できます。
updateValue(_:forKey:) メソッドは、辞書のバリューの型のオプショナル値を返します。例えば辞書が String を保持している場合、このメソッドは String?(オプショナル String)を返します。このオプショナル値は更新前にバリューが存在していた場合はその値のオプショナルを返し、存在していなかった場合は nil を返します:
1
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
2
print("The old value for DUB was \(oldValue).")
3
}
4
// The old value for DUB was Dublin.
Copied!
subscript 構文を使用して特定のキーのバリューを取得することもできます。バリューの存在しないキーに対してもリクエストすることが可能で、バリューの型のオプショナル値を返します。存在しなければ nil を返します:
1
if let airportName = airports["DUB"] {
2
print("The name of the airport is \(airportName).")
3
} else {
4
print("That airport isn't in the airports dictionary.")
5
}
6
// The name of the airport is Dublin Airport.
Copied!
subscript 構文を使用して、キーに nil を代入することで、キーバリューペアを削除できます:
1
airports["APL"] = "Apple International"
2
// "Apple International" APL の空港ではないので削除します
3
airports["APL"] = nil
4
// APL は辞書から削除されました
Copied!
他の方法として、removeValue(forKey:) メソッドを使用してキーバリューペアを削除できます。バリューが存在すれば削除した値を返し、存在しなければ nil を返します:
1
if let removedValue = airports.removeValue(forKey: "DUB") {
2
print("The removed airport's name is \(removedValue).")
3
} else {
4
print("The airports dictionary doesn't contain a value for DUB.")
5
}
6
// The removed airport's name is Dublin Airport.
Copied!

辞書の繰り返し処理(Iterating Over a Dictionary)

for-in ループを使用して辞書のキーバリューペア全部に繰り返し処理することができます。各アイテムは (key, value) のタプルを返し、繰り返し処理の中で、このタプルを一時的な定数や変数に展開することができます。
1
for (airportCode, airportName) in airports {
2
print("\(airportCode): \(airportName)")
3
}
4
// LHR: London Heathrow
5
// YYZ: Toronto Pearson
Copied!
for-in ループについては、For-In Loops(For-In ループ)を参照ください。
keysvalues プロパティを使用して、キーとバリューそれぞれのリストを取得することもできます:
1
for airportCode in airports.keys {
2
print("Airport code: \(airportCode)")
3
}
4
// Airport code: LHR
5
// Airport code: YYZ
6
7
for airportName in airports.values {
8
print("Airport name: \(airportName)")
9
}
10
// Airport name: London Heathrow
11
// Airport name: Toronto Pearson
Copied!
Array インスタンスを引数に受け取る API で辞書のキーとバリューを使いたい場合、keysvalues プロパティを使用して新しい配列を初期化してください:
1
let airportCodes = [String](airports.keys)
2
// airportCodes is ["LHR", "YYZ"]
3
4
let airportNames = [String](airports.values)
5
// airportNames is ["London Heathrow", "Toronto Pearson"]
Copied!
Dictionary 型には決まった順序がありません。特定の順番で値を繰り返し処理をしたい場合、keysvalues プロパティの sorted() メソッドを使いましょう。