22
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Swift] enumerated() には注意が必要

Last updated at Posted at 2021-02-09

はじめに

Swift では繰り返しの処理を行う際、よく for-in 文を使います。
for-in 文はコレクションなどに含まれる要素を1つずつ取り出し処理するのに便利です。
そこで、enumerated() を使うと思うのですが問題点があるため解説していこうと思います。

解説

配列を生成し、enumerated() を用いて配列から要素を取得して見たいと思います。

example01.swift
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() を使ってみました。

example02.swift
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(::) を使うことが推奨されています。

  • ↓ サンプルコード
example.swift
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

問題なく配列から要素と要素番号を取得することができました。

さいごに

今回、一定の条件で配列から要素と要素番号を取り出す方法が必要になったためこのような方法を知る良い機会になりました。
他にも配列を使う機会は多々あると思うので、改めていい勉強になったと思います。

ここまで見ていただきありがとうございます、皆様の学びの助けになれば幸いです。

参考文献

22
11
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?