配列

宣言

Swiftの配列には要素の型を指定できます。配列は、"["と"]"の間に型名を挟んで宣言します。また要素を参照するには、インデックス(0〜)を"["と"]"で囲って指定します。


let party: [String] = ["勇者", "戦士", "魔法使い", "僧侶"]
print(party[2])   // 魔法使い
let hitPoints: [Int] = [140, 210, 85, 52]
print(hitPoints[1]) // 210

型は初期値から推測されるので、初期値を与える場合は型を明示する必要はありません。


let party = ["勇者", "戦士", "魔法使い", "僧侶"]
let hitPoints = [140, 210, 85, 52]

次の様にして配列の全て同じ値を持った要素で初期化することが出来ます。


var hitPoints = Array(count: 4, repeatedValue: 100)  // [100, 100, 100, 100]
var heights = [Double](count: 4, repeatedValue: 170) // [170.0, 170.0, 170.0, 170.0]

配列は初期化時に異なる型の要素を含めることもできますが、その場合各要素の型は、Any又はAnyObjectという特殊な型になります。

Anyは、文字列や数値、クラスのインスタンス等、関数型以外の全ての型を表す汎用的な型です。AnyObjectも汎用的な型ですが、クラスのインスタンスを表します。(CocoaのNSObjectに相当)


var a: Array<Any> = [100, 123.4, "文字列"] // 異なる型の要素
print(50 + (a[0] as Int)) // 計算等する場合はキャスト(型変換)が必要

関数を配列の要素にすることも可能です。


let add = { (a: Double, b: Double) -> Double in return a + b }
let sub = { (a: Double, b: Double) -> Double in return a - b }
let mul = { (a: Double, b: Double) -> Double in return a * b }
let div = { (a: Double, b: Double) -> Double in return a / b }
var ope: [(Double, Double) -> Double]
ope = [add, sub, mul, div]

ope[2](10, 20)  // 200 (= 10 * 20)

AnyとAnyObjectは似ていますが、AnyObjectがクラスのインスタンスを表すのに対して、Anyは、struct型やenum型、数値、文字列等、Swiftのあらゆる型を表します。Objective-Cでは配列にNSArrayを使用しますが、NSArrayは要素の型情報を持たないため、SwiftとObjective-Cで配列をやりとりする場合は、Array<AnyObject>を使用します。(SwiftにはObjective-Cにない型も存在するためAnyを使ってObjective-Cとのやりとりはできません。)

空の配列は次のように宣言できます。


// 全て文字列の空の配列を宣言
var partyA: [String] = []
var partyB: Array<String> = []
var partyC = [String]()

配列中の要素の数は、countプロパティで取得できます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
print("パーティの人数は、\(party.count)人です。")  // パーティの人数は、4人です。

配列が空かどうかは、isEmptyプロパティで調べることができます。


var a: [Int] = []
if a.isEmpty {
    print("配列は空です。")
}

要素の追加

配列の末尾に要素を追加するには、appendメソッドを使います。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party.append("盗賊")   // ["勇者", "戦士", "魔法使い", "僧侶", "盗賊"]

また、+=演算子を使って他の配列の内容を追加することもできます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party += ["侍", "錬金術師"]  // ["勇者", "戦士", "魔法使い", "僧侶", "盗賊", "侍", "錬金術師"]

宣言時の値と異なる型の値を混在させることはできません。


var party: [String] = ["勇者", "戦士", "魔法使い", "僧侶"]
party.append(100)    // エラーになる

定数の配列は、要素を変更したり追加することはできません。


let party = ["勇者", "戦士", "魔法使い", "僧侶"]
party.append("盗賊")   // エラーになる
party[1] = "盗賊"   // エラーになる

要素を指定位置に挿入するには、insertメソッドを使います。第2引数にインデックスを渡します。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party.insert("盗賊", atIndex:2)   // ["勇者", "戦士", "盗賊", "魔法使い", "僧侶"]

要素の変更

変更する要素のインデックスを"["と"]"で囲んで指定し、値を変更します。インデックスの範囲外を指定したり、異なる型の値を代入するとエラーになります。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party[2] = "盗賊" // ["勇者", "戦士", "盗賊", "僧侶"]
party[4] = "侍" // インデックス範囲外を指定すると実行時エラーになる
party[2] = 100  // 配列の宣言時と異なる値を代入するとコンパイル時エラーになる

インデックスの範囲を指定して、値を変更することができます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
// インデックス1の値(インデックス2は含めない)を変更
party[1..<2] = ["侍", "盗賊"]   // ["勇者", "侍", "盗賊", "魔法使い", "僧侶"]

var party = ["勇者", "戦士", "魔法使い", "僧侶"]
// インデックス1〜2の値を変更
party[1...2] = ["侍", "盗賊"]   // ["勇者", "侍", "盗賊", "僧侶"]

範囲指定には、終了インデックスを含めない書き方(開始インデックス..<終了インデックス)と、終了インデックスまで含める書き方(開始インデックス...終了インデックス)があります。

要素の削除

removeAtIndexメソッドを使うと、指定したインデックス位置の要素を削除できます。削除されたインデックス以降の要素が前方に詰められます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party.removeAtIndex(2)  // ["勇者", "戦士", "僧侶"]

removeLastメソッドを使うと、配列の最後の要素を削除できます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
party.removeLast()  // ["勇者", "戦士", "魔法使い"]

既に型情報をもっている配列は、[]を代入することで初期化できます。


var party = ["勇者", "戦士", "魔法使い"]    // ["勇者", "戦士", "魔法使い"]
party.append("盗賊")                      // ["勇者", "戦士", "魔法使い", "盗賊"]
:
party = []                               // []

イティレーション

配列は次のようにfor文を使って繰り返し処理ができます。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
for chara in party {
    print(chara)
}

インデックスも使いたい場合は、配列をenumerate関数に渡してその戻り値を使います。enumerate関数は、配列のインデックスと要素から構成されるタプルを返します。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
for (index, chara) in enumerate(party) {
    print("\(index + 1): \(chara)")
}
/*
1: 勇者
2: 戦士
3: 魔法使い
4: 僧侶
*/

配列のコピー

配列を別の変数に代入すると、その配列は元の配列とは別物になります。そのため、新しい配列の値を変えても元の配列の値は変わりません。


var party = ["勇者", "戦士", "魔法使い", "僧侶"]
var party2 = party
party2[1] = "盗賊"
print(party)      //  ["勇者", "戦士", "魔法使い", "僧侶"]  元の値のまま
print(party2)     //  ["勇者", "盗賊", "魔法使い", "僧侶"]