Swift中高階函式 Map,Flatmap,Filter,Reduce的用法

語言: CN / TW / HK
  • map:map方法作用是把陣列[T]通過閉包函式把每一個數組中的元素變成U型別的值,最後組成陣列[U]。定義如下:\ func map(transform: (T) -> U) -> [U]
  • filter就是篩選的功能,引數是一個用來判斷是否篩除的篩選閉包,根據閉包函式返回的Bool值來過濾值。為True則加入到結果陣列中。定義如下:\ func filter(includeElement: (T) -> Bool) -> [T]
  • reduce的作用給定一個型別為U的初始值,把陣列[T]中每一個元素傳入到combine的閉包函式裡面,通過計算得到最終型別為U的結果值。定義如下:\ func reduce(initial: U, combine: (U, T) -> U) -> U
為什麼要使用Map,Filter,Reduce
-   方便:程式碼量極少,節省時間
-   簡潔:符合Swift語言風格,當你使用map,filter,reduct的程式碼質量會更好。 
    但也需要在合適的場景中使用它們,不要指望用它們來解決任何問題。沒有放之四海而皆準的真理。
-   效率:資料比較大的時候,高階函式會比傳統實現更快,因為它可以並行執行(如執行在多核上),
    除非真的需要更高定製版本的map,reduce和filter,否則可以一直使用它們以獲得更快的執行速度。

Map

在OC中,對陣列元素的操作是很不方便的一件事,遍歷,操作,賦值給新陣列,顯得太繁瑣。\ 在swift中,對陣列的操作就簡潔了很多。

map方法作用是把陣列[T]通過閉包函式把每一個數組中的元素變成U型別的值,最後組成陣列[U]\ 原型如下:\ func map(transform: (T) -> U) -> [U]

Functional Programming in Swift中,實現了map函式如下:

func map<T, U>(xs: [T], f: T -> U) -> [U] { var result: [U] = [] for x in xs { result.append(f(x)) } return result }

  • 將示例陣列,每個數字都加10,獲得一個新的陣列:

``` //map函式裡面可以直接使用函式作為引數,這裡採用函式的方式。 let numberArray = [1,2,3,4,5]

func fmap(a : Int) -> Int{ return a + 10 }

var result = numberArray.map(fmap)

print(result) ```

//採用閉包的方式 var result = numberArray.map({($0) + 10}) print(result)

  • map不只是可以用來做簡單的數值運算,還可以處理一些其他複雜操作,如:在數字後拼接字串,返回新的陣列

用常規方式寫:

for number in numberArray { stringsArray.append("\(number)只") } print(stringsArray)

使用map:

resultArray = numberArray.map({"\($0)只"}) print(resultArray)

如此簡潔,嘗試一下用OC實現的話。。。

FlatMap

flatMap 更加強大,可以傳入N個處理方法,將處理後得到資料,組合到同一個陣列中

``` resultArray = numberArray.flatMap({["($0)個","($0 )只"]}) print(resultArray) //輸出結果:

["1個", "1只", "2個", "2只", "3個", "3只", "4個", "4只", "5個", "5只"] ```

Filter

filter就是篩選的功能,引數是一個用來判斷是否篩除的篩選閉包,根據閉包函式返回的Bool值來過濾值。為True則加入到結果陣列中。定義如下:\ func filter(includeElement: (T) -> Bool) -> [T]

  • 找出陣列中大於2的數

常規方式實現:

var filteredArray : [Int] = [] for number in numberArray { if number > 2 { filteredArray.append(number) } } print(filteredArray)

使用filter實現:

filteredArray = numberArray.filter({$0 > 2}) print(filteredArray)

reduce

reduce的作用給定一個型別為U的初始值,把陣列[T]中每一個元素傳入到combine的閉包函式裡面,通過計算得到最終型別為U的結果值。

定義如下:\ func reduce(initial: U, combine: (U, T) -> U) -> U

reduce的類似實現是:

``` func reduce(arr: [A], _ initialValue: R, combine: (R, A) -> R) -> R { var result = initialValue for i in arr { result = combine(result, i) } return result }

let input = [1, 2, 3, 4]

var sum = reduce(input, 0){ x, y in x + y } ```

reduce函式還可以用來實現map函式和filter函式:

``` func mapUsingReduce(xs: [T], f: T -> U) -> [U] { return reduce(xs, []){ result, x in result + [f(x)] } }

var result = mapUsingReduce(input){ x in x * 3 } result1

func filterUsingReduce(xs: [T], check: T -> Bool) -> [T] { return reduce1(xs, []) { result , x in return check(x) ? result + [x] : result } }

result = filterUsingReduce(exampleFiles) { file in file.hasSuffix("swift") } ```

  • 計算陣列中所有數字的和,積

常規方式實現:

``` var sum = 0 for number in numberArray { sum += number } print(sum)

var product = 1 for number in numberArray { product = product * number } print(product) ```

使用reduce實現:

sum = numberArray.reduce(0, combine: {$0 + $1}) print(sum)

也可以寫為:

sum = numberArray.reduce(0, combine: +)