[Swift] 配列要素をインデックスと組み合わせて処理する

Swift

配列をループするときに、要素だけ や インデックスだけ でなく、その両方を取得しながらループする方法を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Big Sur 11.3 beta
  • Xcode 12.4

配列、インデックスと配列要素

Swift で配列 (Array) はよく使います。

例えば以下のような配列が定義されているとします。

定義された配列

配列に対しては、多くの場合は、順番に要素をアクセスするか、indices を使って、添字アクセスすると思います。

配列要素を順番にアクセスする

順番にアクセス

ループ内では、配列の要素(datum)が取得できるので 個々の要素を処理することができます。

よく使う使い方ですが、datum が配列 data の中の何番目かの情報(インデックス情報)は取得できません。

ですので、処理中で前後の情報が必要なケース、例えば n 番目の要素処理に、n+1 番目の要素が必要な時には、工夫が必要となります。

配列を indices を使って添字アクセスする方法

indices 使用例

ループ内では、インデックス (index)が取得できるので コレクションに添字アクセスすることで要素を取得し処理することができます。

こちらもよく見る使われ方です。気になる点としては、添字アクセスは、範囲外の数字を添字として渡されると、落ちてしまうことでしょうか。

あまり知られていない enumerated()

コレクションの要素 と要素のインデックスの両方をループ中に使用したい時に便利な enumerated というメソッドがあります。

enumerated の定義

Apple のドキュメントは、こちら

以下のような使い方をします。

enumeratedの使用例

enumerated からは、offset と element がペアになったシーケンスが返されます。

この offset は、必ず 0 から開始されるインデックスです。

ループ中で、要素とインデックスの両方が必要となる時に便利なメソッドです。

enumerated のインデックスと元のコレクションのインデックスが一致しないケース

enumerated の対象が Array であれば問題ありません。ですが、スライス 例えば、ArraySlice であるときは、enumerated で得られる 0スタートのインデックスは、コレクションのインデックスと一致しないことがあります。

example

上記は、ArraySlice から enumerated で取得しているケースです。
ArraySlice は、元のArray の一部を使用している関係で indices が 0 スタートでない時がありますが、そのような時が、enumerated のインデックスを添字アクセスにそのまま使うことができないケースになります。

まとめ:配列を インデックス・要素 の両方を取得してループする方法

配列を インデックス・要素 の両方を取得してループする方法
  • enumerated を使うと、インデックスと要素の両方を取得しつつループできる
  • 注意:enumerated が返す インデックスは、必ず 0 スタートで、スライス等から生成されている時は、元のコレクションのインデックスとは一致しないかもしれない

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

Swift おすすめ本

Swift を深く理解するには、以下の本がおすすめです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です