Swiftで遊ぼう! - 361 - Swift 3.0:Set
- Swiftで遊ぼう!の前書き-> Life-LOG OtherSide
- 私の本業、オフィシャルなブログ-> Life-LOG
- Swift 3 対応
2016年11月1日:Swift 3向けに変更
2016年7月5日:改訂
プロジェクト「Sections」に取り組んでいるのですが、コードの内容で分からないところがあるので、「The Swift Programming Language」を読んでいます。Swift1.2とSwift2.0と少し変化がありました。そして2016年7月の段階のSwift 3.0でも修正があるので変更します。
Set
同型の異なる値のコレクションですが並び順は考慮されません。Array型とよく似ているのですが、Objective-CのAPI(フレームワーク)を利用するために存在するので、Objective-CのNSSetと互換性があります。
hashable(ハッシュ可能)
「ハッシュ値(hash value)」とは元のデータから一定の計算により求められた「規則性の無い固定長の値」だそうです。この「一定の計算」のことを「ハッシュ関数」と呼ぶようですが、ハッシュ値から元のデータを復元することはできません。情報内容を欠損させる計算過程を取るので不可逆になります。ということで、同一の固定長の値(ハッシュ値)を持つことのできる元のデータ型をhashable(ハッシュ可能)といいます。
Setで設定できる「型」はハッシュ可能でなければならないルールがあります。そしてハッシュ値は「Int型」になります。
Swiftに用意されている標準的な「型」、String、Int、Double、そしてBoolなど、すべてハッシュ可能なんで、Setの型やDictionaryの「key」に使えます。
Set型のシンタックス
var a: Set<Element> = [] // これが基本形で、<Element>はAnyObjectです。 // そして以下のように宣言できます。 // 宣言時に「Set」を省略することができません。 var b: Set<String> = [] b = ["one", "Two"]
SetもArrayと同様で色々編集できます。
var c: Set = ["Six", "Seven", "Eight", "Nine"] for element in c { print("\(element)") } // Six // Nine // Eight // Seven // 並びは考慮されません。 for element in c.sorted() { print("\(element)") } // Eight // Nine // Seven // Six // 並び順はアルファベット順にソートされます。
変更ではないのですが、remove()の扱いを間違えないようにしないといけませんね。
var d: Set = ["One", "Two", "Three"] d.count / /3 if !d.isEmpty { print("I have values.") } // I have valurs. d.insert("Four") // 加わります。 var r = d.remove("One") // remove()メソッドで取りだしは、 // オプショナル扱いなので、rには // Optional"One"が入ります! r ?? "NoValue" // ということでこうすれば、r = "One"になります。
基本オペレーション
Setには色々なオペレーションがあり覚えておく必要があるでしょう。なかなか覚えられないんですけどね。
// 上からの続きで「c」に新しいコレクションを設定させます。 c = ["Four", "Five", "Six", "Seven"] // 「d」にも新しいコレクションを設定します。 d = ["Six", "Seven", "Eight", "Nine"]
c.intersection(d) // {"Six", "Seven"} c.symmetricDifference(d) // {"Nine", "Four", "Eight", "Five"} c.union(d) // {"Six", "Four", "Nine", "Five", "Eight", "Seven"} c.subtract(d) // {"Four", "Five"}
ということです。
Setの項目と等式
次のイメージの3つのSet、「a」「b」「c」を使って等式の説明をします。
- ==は2つのSetの中身が全く同じなら「true 」を返します。
- isSubset(of:)は、of引数で与えたSetのサブセットであれば「true」を返します。
- isSuperset(of:)は、of引数で与えたSetのスーパーセットであれば「true」を返します。
- isStrictSubset(of:)/isStrictSuperset(of:)は、of引数で与えられたサブセット/スーパーセットで、決して同じではないなら「true」を返します。
- isDisjoint(with:)は、2つのSetに交わりが無いと「true」を返します。
let houseAnimals: Set = ["🐶", "🐱"] let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"] let cityAnimals: Set = ["🐦", "🐭"] let copyAnimals: Set = houseAnimals houseAnimals == copyAnimals // true houseAnimals.isSubset(of: farmAnimals) // true farmAnimals.isSuperset(of: houseAnimals) // true farmAnimals.isDisjoint(with: cityAnimals) // true
これだけです。