☆これ
let arr = ["a","1","b","2"].reduce([]){$0 + (Int($1).map{[$0]} ?? [] )} print(arr) //[1, 2]
QiitaのSwift記事でこういう処理に遭遇したのですが、なんでそうなるのか理解できなくて半日ほど悩んだのでメモ。
要は文字と数字を含む文字列配列 ["a","1","b","2"] から数字だけ抽出して [1, 2] に変換するっていう処理。
★元にした記事はコチラ
qiita.com
koherさんのコメントにある処理です。
☆とりあえず現状の理解
- reduceの初期値を空配列とします([])
- ショートハンド引数が $0,$1,$0 の順番で出現しています
- 最初の$0,$1はreduceのtotal,valueに相当する
- 最後の$0はmapの引数
- 型変換をしているInt($1)の戻り値はOptional型で返却される
- 従ってmapはOptionalのメソッドとなる(要素がひとつの配列のmapと同様の振る舞い)
- map処理で[$0]と括弧で囲んでいるのは配列要素として返却するため
- "??"によってnilの場合には空配列要素を設定("a"などの文字の場合にnilとなる)
- !(アンラップ)やif,guardを用いたOptional Bindingと同様に、非オプショナル型を扱う処理を行っています
- 結果、$0(total) + $1(value)[数値のみの配列要素] とする事で、数値配列を生成しています
☆ショートハンドを使わずにreduceの処理を書いてみた
let arr2 = ["a","1","b","2"].reduce([]){ (total,value)->Array<Int> in guard var chk = Int(value) else{ //Optional Binding return total } return total + [chk] } print(arr2) //[1, 2]
mapと"??"を使わず、素直にguardを使って処理を書いてます。
Array返却なので戻り値の型はArray
一見簡単そうに見えたSwiftですが、なかなか難しそう…(勉強中)
☆蛇足
SwiftはWeb上のsandboxでカジュアルに動作を確認する事ができます。
冒頭のコードを張り付けて実行すると[1,2]が出力されます。
詳細!Swift 3 iPhoneアプリ開発 入門ノート Swift 3+Xcode 8対応
- 作者: 大重美幸
- 出版社/メーカー: ソーテック社
- 発売日: 2016/12/20
- メディア: Kindle版
- この商品を含むブログを見る