【Swift】集合型

集合型とは、配列型や辞書型と同じコレクション型の1つで、複数のデータをまとめて入れておける型です。
書式は配列に似ていますが順序を保証しないこと、同一の値を入れられないことが挙げられます。
複数の値を扱いたいが順序は必要なく同一の値を扱わない場合、集合型同士を演算して要素を比較したい場合などが使い道になると思います。

setアイキャッチimg

前回は 辞書型 について書きました。

今回は 集合型 について書いていこうと思います。

集合型とは

集合型 とは、配列型や辞書型と同じコレクション型の 1 つで、複数のデータをまとめて入れておける型です。
書式は配列に似ていますが順序を保証しないこと、同一の値を入れられないことが挙げられます。
複数の値を扱いたいが順序は必要なく同一の値を扱わない場合、集合型同士を演算して要素を比較したい場合などが使い道になると思います。

使う時に注意するポイント

  • 要素の順序が保証されない
  • 要素の値は全て異なる値でなければならない
  • 配列型とは違いインデックス番号でアクセスはできない
  • 代入する要素は全て同じ型でなければならない

集合型の書式

var 変数名:Set<要素の型名> = [値, 値, 値, ...]

変数名の後に : で区切って、Set キーワードを書きます。
その後 < > の中に要素の型名を書いて、[ ] の中に全て同じ型の要素を複数書きます。

型推論を使って宣言する場合の書式

var 変数名:Set = [値, 値, 値, ...]

変数名の後に : で区切って、Set キーワードを書きます。
その後 [ ] の中に全て同じ型の要素を複数書きます。
代入した値によって型が推論されます。

※ どちらの書式も配列のリテラルと同じなので Set キーワードが必要です

空の集合型を宣言したい場合

集合型の宣言だけしておいて、後から要素を入れたい場合などに空のまま初期化する事ができます。

//書式1
var 変数名 = Set<要素の型名>()

//書式2
var 変数名:Set<要素の型名> = []

書式 1 と 2 どちらでも空の集合のまま初期化( インスタンス化 )する事ができます。

集合型を使った例

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]

print(type(of: draque)) //Set<String>
print(draque) //["キメラ", "スライム", "ブラウニー"]

型推論を使った集合型の宣言例

//型推論
var drague:Set = ["スライム", "ブラウニー", "キメラ"]

print(type(of: drague)) //Set<String>
print(drague) //["キメラ", "スライム", "ブラウニー"]

集合型は要素の順序を保持しないので、アクセスする度に順序が変わります。

要素を追加する方法

集合型の要素を追加したい場合は、insert メソッドを使います。

集合型の変数名.insert(追加したい値)

要素を追加する例

2 つの要素を追加してみようと思います。

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]
print(type(of: draque)) //Set<String>
print(draque) //["キメラ", "スライム", "ブラウニー"]

//要素を追加
draque.insert("スライムナイト")
draque.insert("おどるほうせき")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

これで要素が 2 つ追加できました。

既存の値を追加してみる

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]
print(type(of: draque)) //Set<String>
print(draque) //["キメラ", "スライム", "ブラウニー"]

//要素を追加
draque.insert("スライムナイト")
draque.insert("おどるほうせき")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

//既存の値を追加
draque.insert("スライム")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

集合型の要素は全て異なる値でなければならないので、追加した値がすでに含まれていた場合、追加しても結果は変わりません。

要素を削除する方法

集合型の要素を削除したい場合は、remove メソッドを使います。

集合型の変数名.remove(削除したい値)

削除したい値はそもそも含まれていない( nil )可能性があります。
なので削除したい値を一度変数に代入して、あったら削除、無かったら代わりの値を出力するといった書き方にすると安全です。

var 変数名 = 集合型の変数名.remove(削除したい値)
集合型の変数名.remove(変数名 ?? 代わりの値)

または
var 変数名:型名? = 削除したい値
集合型の変数名.remove(変数名 ?? 代わりの値)

変数に入れる削除したい値は、無い( nil )可能性がある値なのでこの変数は Optional型 になります。
?? 演算子を使って削除したい値と同一の値が、集合に含まれていればアンラップして削除、含まれていなければ右辺の代わりの値を出力するようにします。

要素を削除する例

2 つの要素を削除してみようと思います。

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]
print(type(of: draque)) //Set<String>
print(draque) //["キメラ", "スライム", "ブラウニー"]

//要素を追加
draque.insert("スライムナイト")
draque.insert("おどるほうせき")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

//既存の値を追加
draque.insert("スライム")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

//要素を削除
//削除したい値を変数に代入する
var removeMonster = draque.remove("キメラ")
var removeMonster2 = draque.remove("スライム")
draque.remove(removeMonster ?? "nil")
draque.remove(removeMonster2 ?? "nil")
print(draque) //["スライムナイト", "おどるほうせき", "ブラウニー"]

集合から 2 つの要素が減っています。
これで安全に 2 つの要素を削除できました。

含まれていない値を削除してみる

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]
print(type(of: draque)) //Set<String>
print(draque) //["キメラ", "スライム", "ブラウニー"]

//要素を追加
draque.insert("スライムナイト")
draque.insert("おどるほうせき")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

//既存の値を追加
draque.insert("スライム")
print(draque) //["スライム", "ブラウニー", "キメラ", "スライムナイト", "おどるほうせき"]

//要素を削除
//削除したい値を変数に代入する
var removeMonster = draque.remove("キメラ")
var removeMonster2 = draque.remove("スライム")
draque.remove(removeMonster ?? "nil")
draque.remove(removeMonster2 ?? "nil")
print(draque) //["スライムナイト", "おどるほうせき", "ブラウニー"]

//含まれていない値を削除
removeMonster = draque.remove("はぐれメタル")
print(removeMonster ?? "nil") //nil

含まれていない値を削除しようとしているので、“nil” が出力されています。

setコードimg

集合型とよく使うメソッドとプロパティ

.contains メソッド

.contains メソッドは、指定した要素が含まれているかどうかを Bool値 で返すメソッドです。
指定した要素があれば true
指定した要素がなければ false が返ってきます。

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]

//.containsメソッド
print(draque.contains("スライム")) //true
print(draque.contains("メタルスライム")) //false

.count プロパティ

.count プロパティは、要素の数を取得する事ができるプロパティです。

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]

//.countプロパティ
print(draque.count) //3

.isEmpty プロパティ

.isEmpty プロパティは、要素が含まれているかどうかを Bool値 で取得することができるプロパティです。
何か要素が入っていれば false
何も入ってなければ true を取得します。
要素が 1 つでも入っていれば false 、空であれば true になります。

var draque:Set<String> = ["スライム", "ブラウニー", "キメラ"]

//.isEmptyプロパティ
print(draque.isEmpty) //false
setコードimg2

集合型の演算

メソッドを使って集合の演算をしていきます。
書式は、

集合A.メソッド名(集合B)

となります。

和集合

和集合を求めるには、union メソッドを使います。
このメソッドは 2 つの集合の を返します。
集合型の要素( 値 )は全て異なる値でなければならないので、重複する値があった場合はカウントしません。

var monsterA:Set = ["スライム", "ブラウニー", "キメラ"]
var monsterB:Set = ["スライム", "キングスライム", "メタルスライム"]
var monsterC:Set<String> = []

//和集合
monsterC = monsterA.union(monsterB)
print(monsterC) //["ブラウニー", "キングスライム", "メタルスライム", "キメラ", "スライム"]

積集合

積集合を求めるには、intersection メソッドを使います。
このメソッドは 2 つの集合の を返します。
2 つの集合の重複した要素( 値 )を返します。

var monsterA:Set = ["スライム", "ブラウニー", "キメラ"]
var monsterB:Set = ["スライム", "キングスライム", "メタルスライム"]
var monsterC:Set<String> = []

//積集合
monsterC = monsterA.intersection(monsterB)
print(monsterC) //["スライム"]

差集合

差集合を求めるには、subtracting メソッドを使います。
このメソッドは、2 つの集合の を返します。
集合 A から 集合 B の重複した要素( 値 )を除いて返します。

var monsterA:Set = ["スライム", "ブラウニー", "キメラ"]
var monsterB:Set = ["スライム", "キングスライム", "メタルスライム"]
var monsterC:Set<String> = []

//差集合
monsterC = monsterA.subtracting(monsterB)
print(monsterC) //["キメラ", "ブラウニー"]

※ 差集合は、集合 A集合 B を反対にすると結果が変わるので注意。

対象差集合

対象差集合を求めるには、symmetricDifferene メソッドを使います。
このメソッドは、2 つの集合の 対象差 を返します。
2 つの集合の重複した要素( 値 )以外を返します。

var monsterA:Set = ["スライム", "ブラウニー", "キメラ"]
var monsterB:Set = ["スライム", "キングスライム", "メタルスライム"]
var monsterC:Set<String> = []

//対象差集合
monsterC = monsterA.symmetricDifference(monsterB)
print(monsterC) //["キメラ", "ブラウニー", "キングスライム", "メタルスライム"]

この他にも Swift にはいろいろなパターンの演算ができるメソッドが用意されています。

setコードimg3

以上 集合型 についてでした。

次回は break文 と continue文 について書いていこうと思います。

実行環境

version
Xcode 14.2 (14C18)
Swift 5.2.4

公式ドキュメント

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/

投稿者: tomo

30代経験ゼロからプログラミングを始めて、趣味でiOSのアプリを作って遊んでる人。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です