はじめに
Swift では繰り返しの処理を行う際、よく for-in 文を使います。
for-in 文はコレクションなどに含まれる要素を1つずつ取り出し処理するのに便利です。
そこで、enumerated() を使うと思うのですが問題点があるため解説していこうと思います。
解説
配列を生成し、enumerated() を用いて配列から要素を取得して見たいと思います。
let array = ["A", "B", "C", "D", "E"]
for (i, value) in array.enumerated() {
print(i, array[i])
}
// 結果
//0 A
//1 B
//2 C
//3 D
//4 E
このように一見問題なく処理できたように思えます。
どこか駄目なのかというと、i です。この i は配列の要素番号ではなく、0を始めとしたカウンターになっています。
以下のように公式のドキュメントでも説明されています。
the integer part of each pair is a counter for the enumeration, not necessarily the index of the paired value
次に ArraySlice を行い array 配列から array2 部分配列を取得し、再度 enumerated() を使ってみました。
let array = ["A","B","C","D","E"]
let array2 = array.dropFirst()
for (i, value) in array2.enumerated() {
print(i, array2[i])
}
// 解説
// 0 A <- アクセスできないためエラー
// 部分配列の中身 (array2)
// array2 = ["B", "C", "D", "E"]
実行してみると Index out of bounds というエラーが返されました。
これは dropFirst() を使い array 配列 の先頭を切り取ったため起こったものです。
enumerated() の i は0始まりの数値を返すため、array2 配列 には array2[0] = A が存在しないためアクセスできず、エラーとなるわけです。
公式ドキュメントでは zip(::) を使うことが推奨されています。
- ↓ サンプルコード
let array = ["A","B","C","D","E"]
let array2 = array.dropFirst()
for (i, value) in zip(array2.indices, array2) {
print(i, array2[i])
}
// 結果
//1 B
//2 C
//3 D
//4 E
問題なく配列から要素と要素番号を取得することができました。
さいごに
今回、一定の条件で配列から要素と要素番号を取り出す方法が必要になったためこのような方法を知る良い機会になりました。
他にも配列を使う機会は多々あると思うので、改めていい勉強になったと思います。
ここまで見ていただきありがとうございます、皆様の学びの助けになれば幸いです。