Swift 文法その2 - 配列 -

配列は ["a", "b", "c"] のように複数のデータを1つの変数に保存できます。配列の中にあるデータは要素、要素が配列のどの位置に入っているのかをインデックス番号 で表します。インデックス番号は「0」から始まり、["a", "b", "c"] で言うとaのインデックス番号は「0」、bは「1」、cは「2」です。

let で宣言すると要素の追加、削除、値の変更ができないので注意してください。

 宣言・初期化

var a: [String] = []var b = [String]()var c = ["a"] // データ型なし(型推論)
// 冗長なのであまり使われないがArrayクラスを使用するパターン var d: Array<String> = [] var e = Array<String>()

配列の中に配列を入れることも可能です(「多次元配列」)

var a = [["a", "b"], ["c", "d"]]

要素の追加

a.append("b") // 配列の最後に追加
a += ["b"] // 配列の最後に追加
a.insert("b", at: 1) // 特定のインデックスに挿入

要素の結合
配列と配列同士を結合して要素をまとめることができます。

["a", "b"] + ["c", "d"] // ["a", "b", "c", "d"]["a", "b"].append(contentsOf: ["c", "d"]) // ["a", "b", "c", "d"]

要素の取得

var a = ["a", "b", "c"]

// インデックスを指定
print(a[2]) // "c" 

// 範囲を指定
print(a[0...1]) // ["a", "b"]

要素の更新
インデックス番号を指定して直接代入します。

a[1] = "e"

要素の削除 

a.remove(at: 1// インデックスを指定
a.removeLast() // 最後の要素を削除
a.removeAll() // 全要素を削除

よく使うプロパティ

isEmpty: 要素が空かどうか
count: 要素数

よく使うメソッド

contains : 指定した要素が入っていたら true、なければ false を返します。

["a", "b", "c"].contains("d") // false

filter: 条件に一致する要素を返します。

let result = [1, 2, 3, 4, 5].filter { $0 % 2 == 0 }print(result) // [2, 4]

sort: 配列内の要素を並び替えます。

// 昇順var a = [2, 3, 1]
a.sort { $0 < $1 }
print(a) // [1, 2, 3]
// 降順 a.sort { $0 > $1 }print(a) // [3, 2, 1]

sorted: 配列内の要素は変更せずに、メソッドの返り値で並び替えた後の新しい配列を返します。

// 昇順[2, 3, 1].sorted() // [1, 2, 3]
// 降順
[2, 3, 1].sorted(by: >) // [3, 2, 1]

firstIndex: 指定した要素が配列内で最初に出てくるインデックス番号を返します。ない場合は nil になるので返り値はOptionalなIntです。

[1, 2, 3, 1].firstIndex(of: 1) // Optional(0)[1, 2, 3].firstIndex(of: 4) // nil

map: 要素に特定の処理を加えて結果を配列で返します。

let result =  [1, 2, 3].map { $0 * 2 } // 2倍にする
print(result) // [2, 4, 6]

map 内では $0 で要素を1つずつ取りして処理し、すべての要素を取り終えたら今までの map 内の返り値を配列にして返します。

$0 を省略して map 内のメソッドの引数に自動的に渡すこともできます。

let result = [1, 2, 3].map(String.init)
print(result) // ["1", "2", "3"]


// 要素を関数の引数に渡す
func hoge(i: Int) -> String {
  return String(i)
}

let result = [1, 2, 3].map(hoge)
print(result) // ["1", "2", "3"]

$0ではなく指定の変数名を使用したいという場合は、少し冗長になりますが以下のようにもかけます。

[1, 2, 3].map { (num: Int) -> Int in num * 2 }

numが指定の変数名、 -> Int in の Int は返り値のデータ型です。ここはクロージャーと呼ばれる文法で後日説明する予定です。

補足: map内では返り値を指定する必要があるので通常 .map { return $0 * 2 } と書くのですが、Swift では処理が1行の場合のみ return を省略できることになっています。以下のように2行になる場合は return が必要になります。

let result: [Int] = [1, 2, 3].map {
   let b = $0 * 2
   return b + 1
}
print(result) // [3, 5, 7]

compactMap: map の返り値にnilが含まれていたら排除します。

let result = [1, 2, nil].compactMap { $0 }
print(result) // [1, 2]

flatMap: 多次元配列を1次元配列にします。

let a = [["a"], ["b"], ["c", "d"]].flatMap { $0 }
print(a) // ["a", "b", "c", "d"]

reduce: 要素に特定の処理を加えて結果を返します。mapと違い、1回ループした結果を次のループでも使い、最後のループ処理で返す値がこのメソッドの返り値になります。最初のループ時には前のループの返り値がないので引数に値を渡し、それを使います。 

let result = [1, 2, 3].reduce(0) { $0 + $1 }
print(result) // 6

reduce 内の$0は前のループ時の結果、$1は現在のループで使用している要素です。ループごとの値は以下のようになっています。
1回目のループ
$0: 初期値の0、$1: 1
2回目のループ
$0: 1回目のループの返り値(0+1)、$1: 2
3回目のループ
$0: 2回目のループの返り値(1+2)、$1: 3

そして、最終ループでの 3 + 3 が 6 になるので、reduceの返り値が6になる、という仕組みです。

reduce も map と同様、$0, $1 の代わりに指定の変数名で定義することもできます。

[1, 2, 3].reduce(0) { (prevValue: Int, elementValue: Int) -> Int in prevValue + elementValue }

おさらい

配列の追加や結合は書き方が2通りありますが、チームで開発している時はこういう場合きちんとコーディングルールを設けてどちらかに統一することが多いようです。

多次元配列を使う機会が少ないので flatMap は実務で使ったことはないのですが一応記載しておきました。

reduceは初めて学ぶ方にとっては最初うまく頭で理解できないかもしれないですが、「配列の値を合計したい時に利用する」くらいのイメージでよいと思います。

次回は「辞書」についてご紹介します。

この記事が気に入ったらサポートをしてみませんか?