Swift Tips - 高階函式(map & flatMap & filter & reduce)
官方提供的高階函式,不僅可以大大的簡化我們的程式碼,而且一般來講會比傳統(我們自己實現)的實現更好更快。PS:可能是我自己能力不足,哈哈~
可能有過這樣的苦惱:費勁巴拉的終於實現了,猛然發現官方原本提供了現成的方法,而且比自己實現的更好。
內心彷彿一萬隻草泥馬飄過。。。
總之,你用或者不用,它們就在那裡!
今天主要介紹一下swift
提供的幾個高階函式 ——
map
&
flatMap
&
filter
&
reduce
。
map
函式
map
方法獲取一個閉包表示式作為其唯一引數。 陣列中的每一個元素呼叫一次該閉包函式,並返回該元素所對映的值。
簡單說就是陣列中每個元素通過某個方法進行轉換,最後返回一個新的陣列。
比如下面這個栗子:
//將 Int 型別陣列(各個商品的金額),轉換成 String 型別的陣列(在金額前加上 $ 符號) let prices = [20,30,40] let strs = prices.map({ "$\($0)" }) print(strs) //["$20", "$30", "$40"]
這樣的操作是不是更讓你覺的爽歪歪呢??
flatMap
函式
flatMap
方法同map
方法比較類似,只不過它返回後的陣列中不存在nil
(自動把nil
給剔除掉),同時它會把Optional
解包。
這裡我們也通過個栗子來直觀的理解:
//比較 map 和 flatMap 這兩個方法 let array = ["Apple", "Orange", "Grape", ""] let arr1 = array.map { a -> Int? in let length = a.count guard length > 0 else { return nil } return length } print("arr1:\(arr1)")//arr1:[Opitional(5), Opitional(6), Opitional(5), nil] let arr2 = array.flatMap { a-> Int? in let length = a.count guard length > 0 else { return nil } return length } print("arr2:\(arr2)")//arr2:[5, 6, 5]
除此之外,flatMap
還能把陣列中存有陣列的陣列(二維陣列、N維陣列)一同開啟變成一個新的陣列。
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] let arr1 = array.map{ $0 }// [[1, 2, 3], [4, 5, 6], [7, 8, 9]] let arr2 = array.flatMap{ $0 } // [1, 2, 3, 4, 5, 6, 7, 8, 9]
是不是很優秀??
filter
函式
filter
方法用於過濾元素,即篩選出陣列元素中滿足某種條件的元素。
來來來,舉個簡單的栗子:
//篩選出金額大於 25 的元素。 let prices = [20,30,40] let result = prices.filter({ $0 > 25 }) print(result)//[30, 40]
這樣就不用for
裡面再去if
判斷了不是?
reduce
函式
reduce
方法把陣列元素組合計算為一個值,並且會接受一個初始值,這個初始值的型別可以和陣列元素型別不同。
可能不好理解,來個經典的求和栗子:
let prices = [20,30,40] let sum = prices.reduce(0) { $0 + $1 } print(sum)// 90
甚至,上面的程式碼還能簡化成下面這樣:
let sum = prices.reduce(0, +)
哈哈~ 是不是有點兒意思了??
顯然,reduce
不僅僅是能求和,比如它還能這樣:
let array = ["Apple", "Orange", "Grape"] let str = array.reduce("", { return $0 == "" ? $1 : $0 + "、" + $1 }) print(str)// Apple、Orange、Grape
當然,上面我們只是可以舉個栗子,字串的拼接我們可能會選擇這樣:
let str = array.joined(separator: "、")
平常的需求如此的豐富多彩,總有適合的場景,擇機使用就好~~
而,下面要說的是:其實在各個高階函式之間也是並不孤單的!
組合使用
話不多說,舉個flatMap & filter
組合的栗子:
let collections = [[5,2,7],[4,8],[9,1,3]] let onlyEven = collections.flatMap { $0.filter { $0 % 2 == 0 } } print(onlyEven)//[2, 4, 8]
這樣的栗子還有更好,等你在擼程式碼的過程中不斷的去發現驚喜吧!!
鏈式組合
map&flatMap &filter 這三個函式的返回值仍舊是一個數組,所以我們當然對其返回值繼續進行一些操作,不是麼?
一個栗子:
//將陣列中大於 7 的所有數字進行求和操作。 let marks = [4,5,8,2,9,7] let totalPass = marks.filter{$0 > 7}.reduce(0,+)// 17
再一個栗子:
//對某一個數組裡面的數字進行平方操作然後再篩選出偶數值。 let numbers = [4,5,8,2,9,7] let evenSquares = numbers.map{$0 * $0}.filter{$0 % 2 == 0}// [16, 64, 4]
以上。
希望可以對你有所幫助!!嘎嘎~