LoginSignup
16
9

More than 5 years have passed since last update.

swift 5.0 の map, reduce における index の取り方

Posted at

Array の functional loop (map, reduce) で、要素のindexが取りたい場面があった。

let arr: Array<String> = ["A", "B", "C", "D", "E"]

// $0 $1 を使う書き方

arr.map{ $0 + "F" } 
arr.reduce("", { $0 + $1 }) //=> "ABCDE"

// 定義する書き方

arr.map{ elem in
  elem + "F"
}
arr.reduce("", {acc, cur in
  acc + cur
})

// どちらの書き方でも結果はそれぞれ同じ。
// map --> arr = ["AF", "BF", "CF", "DF", "GF"]
// reduce --> "ABCDE"

今回は例として、奇数番目の要素だけを "X" にしたいとする。

loop内で要素のindexを取得し、 index % 2 == 0 か否か場合分けしたい。

調べると、swift 3.0 までは、要素が格納されている変数 (上の例だと$0, $1, elem, cur)の.0でindexを取得できたようであった。

// swift 3.0 までで可能な書き方

arr.map { $0.0 % 2 == 0 ? "X" : elem }

swift 5.0でこれを行うと、次のようにエラーが出た。

Value of type 'String.Element' (aka 'Character') has no member '0'

解決策としては、配列を一旦 EnumeratedSequence に変換してやる。

そうすると、全ての要素が「値とoffset(=index)のペア」に変わったシーケンスを取得できる。

値には.element、indexには.offsetでアクセスできる。

// swift 5.0 で可能な書き方

arr.enumerated().map { $0.offset % 2 == 0 ? "X" : $0.element }
// --> arr = ["X", "B", "X", "D", "X"]
16
9
0

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
16
9