標籤:
文章內容來自《Functional Programing in Swift》,具體內容請到書中查閱
Map, Filter, Reduce
Functions that take functions as arguments are sometimes called higher- order functions.
higher-order function(高階函數)就是說函數可以作為另一個函數的參數。
在本章,我們將介紹一下swift標準庫中在數組方面的一些相關的高階函數,先介紹一些比較普通的然後介紹如何把這些泛型的操作組織成一個比較複雜的操作。
Introducing Generics (泛型)
// 函數:返回 對原來的數組的每個元素進行加1後的數組
func incrementArray(xs: [Int]) -> [Int] { var result: [Int] = [] for x in xs { result.append(x + 1) } return result }
// 函數:返回 對原來的數組的每個元素進行乘2後的數組
func doubleArray1(xs: [Int]) -> [Int] { var result: [Int] = [] for x in xs { result.append(x * 2) } return result }
你會發現這兩個方法中有很多相似的代碼,能夠將這些不同的地方抽象出來,寫成一個單一,更普通的函數的方式嗎?就如下面:
func computeIntArray(xs: [Int]) -> [Int] { var result: [Int] = [] for x in xs { result.append(/* something using x */) } return result }
為了完成上面的定義,我們將需要一個新的參數用來抽象出這些不同的地方:
func computeIntArray(xs: [Int], f: Int -> Int) -> [Int] { var result: [Int] = [] for x in xs { result.append(f(x)) } return result }
那麼之前的代碼將變成下面:
func doubleArray2(xs: [Int]) -> [Int] { return computeIntArray(xs) { x in x * 2 }}
注意在調用computeIntArray的時候,我們使用過了尾閉包(trailing closures )文法
但是這個computeIntArray還不是很靈活,如果我們支援計算一個數組中的元素是不是偶數:
func isEvenArray(xs: [Int]) -> [Bool] { computeIntArray(xs) { x in x % 2 == 0 }}
不幸的是,這段代碼會報一個類型錯誤。那麼我們該如何解決呢?或許我們會這樣做:
func computeBoolArray(xs: [Int], f: Int -> Bool) -> [Bool] { let result: [Bool] = [] for x in xs { result.append(f(x)) } return result }
但是這樣還是不好,假如我們需要計算的是String?難道我們要定義另外一個高階函數,參數類型為 Int->String ?
we will say "NO"
幸好,這有解決辦法:我們可以使用泛型 (generics):
func genericComputeArray<U>(xs: [Int], f: Int -> U) -> [U] { var result: [U] = [] for x in xs { result.append(f(x)) } return result }
但是你會發現我們這邊還是有個[Int],so:
func map<T, U>(xs: [T], f: T -> U) -> [U] { var result: [U] = [] for x in xs { result.append(f(x)) } return result }
下面我們對上面的一個函數進行改造:
func computeIntArray<T>(xs: [Int], f: Int -> T) -> [T] { return map(xs, f)}
swift之函數式編程(四)