コレクション型 ArrayとDictionary
プログラムでは複数個の同じ型のデータを扱いたいことがよくあります。例えば、学校のテストの得点を管理するプログラムを作成したい場合、人数分のテストの点数を管理する必要があります。生徒数が100人いた場合、テストのデータを変数で管理しようとすると100個の変数が必要になってきます。また、テストが1科目だけならよいですが、3科目あった場合、100×3=500個の変数を用意する必要があります。こういった場合、5科目のテストのデータを1つの変数として表現し、さらに100人分のデータも1つの変数として表現できれば楽にデータを管理できます。複数個のデータを一つの変数として扱える仕組みを提供するのがコレクション型です。Swiftでは配列型と辞書型、2つのコレクション型を用意しています。
配列型
配列は同じ型の複数の値を格納する型です。配列に格納されている値のことを「配列の要素」と呼びます。配列に格納できる値の型は明示的に型注釈で指定するか、型推論のどちらかで明らかにします。例えば、Int型の配列をつくったら、Int型の値以外は配列に挿入することはできないということになります。
配列型の宣言
Swiftの配列型は以下のように宣言することができます。
Array<型名>
型名は配列に格納する値の型になります。以下のように記述しても構いません。
[型名]
例えば、Int型の配列を宣言する場合は次のようになります。
array1、array2いずれもInt型の配列として宣言された変数になります。
配列の初期化処理とイニシャライザ
あるオブジェクトを作成する時、オブジェクトに対して初期値を設定することができます。これをオブジェクトの初期化処理と呼びます。オブジェクトの初期化処理は「型名()」の形で行うことができます。オブジェクトの初期化処理は「イニシャライザ」とも呼ばれています。配列の初期化処理は次のように行えます。
Array<型名>() または [型名]()
型名は配列に格納する値の型になります。次の例はInt型の配列をイニシャライザで初期化しています。
また、配列を初期化する時、同じ値で初期化したいことがよくあります。その場合、次のイニシャライザが利用できます。
Array<型名>(count: xxx, repeatedValue: yyy) [型名](count: xxx, repeatedValue: yyy)
countのxxxには初期化したい要素数、repeatedValueには要素を初期化する値になります。例えば、Int型の配列で3つの要素を0で初期化する処理は次のようになります。
配列リテラル
上記の例ではイニシャライザを利用して配列を初期化しましたが、配列リテラルで初期化することもできます。配列リテラルは複数の値をカンマで区切り、[ ]でくくります。
[値1,値2,値3,...]
次の例はString型の値で配列を初期化した例です。
arrayListはString型の配列として宣言されているので、String型の値のみ保持できます。そして、arrayListの配列は配列リテラルで初期化されています。この配列はString型の値を2つもった配列になります。Swiftでは型推論があるので配列の型を省略することが可能です。
配列へのアクセス
配列は順序を持っており、それぞれの要素には番号を指定してアクセスします。なお、配列の番号は0番が始まることに注意してください。
配列名[番号]
以下は"Peach"と"Apple"という2つの要素をもった配列で、それぞれの要素にアクセスする例です。
arrayList[0]で配列の0番目の要素、つまり文字列"Peach"を取得できます。また、arrayList[1]で配列の1番目の要素、つまり文字列"Apple"を取得できます。
配列の要素の変更
配列の要素番号を指定して値を代入すると、既に存在する値を変更することができます。
また、範囲演算子を利用して範囲内の値を一括で変更することも可能です。次の例では0番目の要素をOrange、1番目の要素をStrawberryに一括で変更した例です。
要素の追加
配列の要素を追加する方法は3つあります。
1.+=演算子を利用してひとつ以上の要素を追加する方法
次の例では配列の末尾に"Pear"を追加しています。また、2行目では1度に"Kiwi"と"Melon"を追加しています。
2.appendメソッドを利用して配列の末尾に要素を追加する方法
次の例では配列の末尾に"Apple"を追加しています。
3.insertメソッドを利用して特定の場所に新しい要素を挿入する方法
次の例では0番目に"Lemon"を追加しています。
要素の削除
要素を取り除くにはremoveAtIndexを利用します。また、removeAtIndexは処理を実行した後、取り除いた要素を返却してくれます。返却された値は定数や変数に代入することができます。次の例は配列の0番目の要素を削除して、削除した値をremoveItemに代入しています。また、配列の要素を削除した場合、配列に空白が生じますが、Array型は空白を自動で埋めてくれます。例えば、0番目の要素を削除した場合、1番目以降の要素をずらして0番目に空白が生じないようにしてくれます。
また、配列の最後の要素を削除したい場合はremoveAtIndexを削除するのが便利です。
配列の要素数
利用している配列の要素数がいくつかを知るにはcountを利用します。
配列が空かどうかをチェック
配列の要素が0かどうかはisEmptyを利用して知ることができます。isEmptyを実行すると配列が空であればtrue、配列が空でなければfalseが返ります。次の例はif文とセットでisEmptyを利用した例です。
配列の要素が空であればempty、空でなければnot emptyを出力します。今回は空ではないのでnot emptyを出力します。
辞書型(Dictionary型)
辞書型は同じ型の値を複数個、保持できる型でそれぞれの値はユニークな識別子と結びつけられます。このユニークな識別子はキーと呼ばれます。つまり、辞書型とはキーと値のペアが複数個存在するデータ型ということになります。辞書型ではキーに紐づく値が存在し、そのキーを指定することで値が取り出すことができます。
辞書型の宣言
辞書型は以下のように宣言することができます。
Dictionary<キー型, 値型>
キー型が辞書型のキーで利用される型、値型が辞書型の値で利用される型です。また、別の書き方として以下のような省略記法も存在します。
[キー型: 値型]
キー型がString型、値型がInt型の辞書型の変数は以下のように宣言できます。
辞書の初期化
辞書は配列同様、オブジェクトです。オブジェクトの初期化処理は「型名()」の形で行うことができます。辞書の場合、以下のように行うことが可能です。
Dictionary<キー型,値型>() もしくは [キー型:値型]()
次の例はキー型がString、値型がInt型の辞書を初期化した例です。
辞書リテラル
辞書リテラルで辞書を初期化することができます。辞書リテラルは辞書のキーと値のペアの形で記述します。キーと値のペアはキーと値がくっついたもので、キーと値はセミコロンで区切ります。キーと値のペアは以下のように記述します。
[key1: value1, key2: value2, key3: value3]
3科目のテストの点数を管理する辞書は次のようにようになります。
キーにString型、値にInt型を指定して辞書型の変数testsを宣言しています。辞書リテラルで変数を初期化する時はキー:値のペアで値を設定して初期化しています。
また、型推論を利用できますので、以下のように簡潔に記述することもできます。
型推論の結果、推論前に存在していた型注釈「:[String: Int]」の部分が省略できました。
辞書のキータイプ
辞書のキーはhashableでなければならないという条件があります。ここではあまり難しく考えずに基本的な型であるString型、Int型、Double型、Bool型は指定できるということ、それ以外の型は指定できない可能性があるということだけ知っておいてもらえればよいです。
辞書の値へアクセス
辞書の値は次のようにしてアクセスできます。
変数名[キー名]
次の例は辞書のキー「Eng」に紐づく値にアクセスする例です。
辞書へアクセスして値を取得した時、注意しなければならないのがオプショナル型で値が渡されることです。このため、オプショナルバインディングを利用した次の例のようにアクセスするといいでしょう。
辞書の値の追加
新しいキーを用意して、その新しいキーに対して値を代入することで値を追加できます。
変数名[キー名] = 値
次の例は新しくキー「Chemistry」を用意して、そのキーに紐づく値77を辞書に追加した例です。
辞書の値を変更
既に存在する特定のキーを指定して、値を変更することもできます。次の例は新しくキー「Chemistry」に対して、値として95を設定しなおした例です。
辞書の要素を削除
既に存在する特定のキーを指定して、nilを代入することで辞書の要素を削除することができます。
辞書の要素数
利用している辞書の要素数がいくつあるのかを知るにはcountを利用します。
また、辞書の要素が0かどうかはisEmptyを利用して知ることができます。