Sponsor Link
環境&対象
- macOS Monterey 12.1 Beta
- Xcode 13.1
- iOS 15
Dictionary
Swift の Standard Library で用意されている型です。
Apple のドキュメントは、こちら。
何らかの値を キー とひもづけて保持しておくことができるコレクションの1つです。
キーは、Hashable であることが必要ですが、定数時間で要素を取得することができます。
存在しないキーの扱い
存在しないキーを使用して値を取得しようとすると nil が返ります。
let dic = [1: "One", 3:"Three"]
print(dic[1]) // One
print(dic[2]) // nil
存在しないキーにデフォルト値を持たせる
キーにひもづけられた値が存在しない時には、nil が返されますが、nil の代わりに 指定したデフォルト値を返すことができます。
Apple のドキュメントは、こちら。
let dic = [1: "One", 3:"Three"]
print(dic[1], default: "I don't know") // One
print(dic[2], default: "I don't know") // I don't know
受け取った側で nil チェックをすることで、同様のことはできますが、シンプルに記述でき わかりやすいコードを書くことができます。
以下は、すこし考察してみたことです。
デフォルト値を持たせたいケース
アプリケーションを作成していて、要素に対して付加的な情報を記憶しておきたい時があります。
モデル要素に付加情報を短期的に記録したいケース(例えば色指定)
特に具体的なユースケースがあるわけではありませんが、例えば、モデルデータにアプリとして付加情報を短期的(例えばそのアプリの実行中のみ)に記憶しておきたいとします。
元のモデルデータに新しい属性を追加することも1つの解決策ですが、個別アプリの必要とする情報を記憶させるためだけに、モデルを拡張していくのはあまりよろしくありません。
以下は、Person の配列を保持しているモデルで、それぞれの Person に対して 指定した色を保持したいとします。
指定色を Array に記録する
Model で保持している PersonList と同じ並びの ColorList を ViewModel に List として定義して保持するようにしました。
import Foundation
import SwiftUI
struct Person: Identifiable {
let id = UUID()
var givenName: String
var familyName: String
}
struct Model {
var personList:[Person] = []
}
class ViewModel {
var model: Model
var colorList:[Color]
init(_ model: Model) {
self.model = model
self.colorList = Array(repeating: Color.white, count: model.personList.count)
}
func setPersonColor(id: Person.ID, color: Color) {
if let index = model.personList.firstIndex(where: {$0.id == id}) {
self.colorList[index] = color
}
}
func personColor(id: Person.ID) -> Color {
if let index = model.personList.firstIndex(where: {$0.id == id}) {
return self.colorList[index]
}
return .white // default color even for invalid person.id
}
}
考察
初期化としてデフォルト色(白)をセットする処理を init で行っていますので、数が増えた時が気になります。
色設定時も、設定色を返す時も、Array を探索する必要がありますので、要素数に応じて処理時間がかかっています。
指定色を Dictionary に記録する
上記の方法でも良いのですが、Dictionary をうまく使って実装することもできます。
ViewModel には、colorDic[Person.ID:Color] という Dictionary 型のインスタンスプロパティを追加します。
class ViewModel {
var model: Model
var colorDic:[Person.ID: Color] = [:]
...
init では、初期化する必要はありません。
setPersonColor は、以下のようになります。
func setPersonColor(id: Person.ID, color: Color) {
self.colorDic[id] = color
}
ID をキーにしている Dictionary を使用しているので、検索する必要はありません。
personColor は、以下のようになります。
func personColor(id: Person.ID) -> Color {
self.colorDic[id, default: .white]
}
設定色を返す時にも、Array 等を検索する必要はなく、Dictionary の該当キーの値を返すだけです。
ポイント
デフォルトの値があるケースでは、Dictionary[key, default:] をうまく使うことができるケースです。
空の辞書から始めて 必要に応じて要素を追加保存していくことで、コンパクトなコードにすることができます。
まとめ:Dictionary をデフォルト値付きで扱う方法
- Dictionary の [key, default:] をうまく使うと デフォルト値付きの Dictionary として扱うことができる
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Swift 学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Swift ポケットリファレンス
Swift を学んでも、プログラミング言語の文法を全て記憶しておくことは無理なので、ちょっとした文法の確認をするために、リファレンス本を手元に置いておくと便利です。
Swift4 までしか対応していないので、相違点を理解して参照する必要があります。
Sponsor Link