せっかくなので関数型で書いてみる
何も考えずにSwiftを書いているといつものオブジェクト指向で書いてしまいます。せっかくなのでArrayクラスで関数型の書き方を試してみます。
Array.map()
map()は配列の各要素に同じ処理を繰り返す場合に使用します。
メドッド名が何故map()なのかニュアンスがよくわかりません。
1.関数型言語は関数を引数で渡せます。
//100を足して返す関数
func plus100(srcVal:Int) -> Int { return srcVal + 100 }
//Arrayのmapメソッドに関数を渡す
let srcArray = [1, 2, 3, ] var array1 = srcArray.map(plus100) XCTAssertEqual(array1[0], 101, "Pass") XCTAssertEqual(array1[1], 102, "Pass") XCTAssertEqual(array1[2], 103, "Pass")
2.同じ処理をクロージャでも書けます
変数名とか型を省略して書くとこんな感じになります
let srcArray = [1, 2, 3, ] let array2 = srcArray.map{ $0 + 100 } XCTAssertEqual(array2[0], 101, "Pass") XCTAssertEqual(array2[1], 102, "Pass") XCTAssertEqual(array2[2], 103, "Pass")
3.変数名と型を明示して書くこともできます。これだと戻り値の型を変えられます。
var array3 = srcArray.map{(srcVal:Int) -> String in return String(srcVal + 100) } XCTAssertEqual(array3[0], "101", "Pass") XCTAssertEqual(array3[1], "102", "Pass") XCTAssertEqual(array3[2], "103", "Pass")
4.クロージャはブロックの外の変数にアクセス可能です
var before = 0 var 配列の一つ前の要素と合計 = srcArray.map{(srcVal:Int) -> Int in let now = before + srcVal before = srcVal return now } XCTAssertEqual(配列の一つ前の要素と合計[0], 1, "Pass") //0 + 1 XCTAssertEqual(配列の一つ前の要素と合計[1], 3, "Pass") //1 + 2 XCTAssertEqual(配列の一つ前の要素と合計[2], 5, "Pass") //2 + 3
Array.filter()
filterは、文字通り任意の基準で配列の要素を抽出するのに使用します。
let srcArray = [1, 2, 3, 4, 5, 6, 7, 8, 9,] let 3の倍数 = srcArray.filter{ $0 % 3 == 0 } XCTAssertEqual(3の倍数[0], 3, "Pass") XCTAssertEqual(3の倍数[1], 6, "Pass") XCTAssertEqual(3の倍数[2], 9, "Pass") XCTAssertEqual(3の倍数.count, 3, "Pass")
Array.reduce()
reduceは前のループの結果を受けて次のループを処理するときに使用する感じでしょうか?
最初の引数の値は初期値となります
let srcArray = [1, 2, 3, ] let sum1 = srcArray.reduce(0) { $0 + $1 } XCTAssertEqual(sum1, 6, "Pass") //初期値0 + 1 + 2 + 3 let sum2 = srcArray.reduce(100) { $0 + $1 } XCTAssertEqual(sum2, 106, "Pass") //初期値100 + 1 + 2 + 3
Array.sorted()
最後はソートです。sortedだと新たなリストを返しますが、sort()だと元の配列自体が並び替えられます。
var srcArray = [3, 1, 4, 2,] let ソートしてみた = srcArray.sorted({ $0 < $1 }) XCTAssertEqual(ソートしてみた[0], 1, "Pass") XCTAssertEqual(ソートしてみた[1], 2, "Pass") XCTAssertEqual(ソートしてみた[2], 3, "Pass") XCTAssertEqual(ソートしてみた[3], 4, "Pass")