在iOS 9以后的版本中,Swift語(yǔ)言中有了兩個(gè)函數(shù),一個(gè)叫做map, 一個(gè)叫做flatMap,這兩個(gè)概念在我們的函數(shù)式編程中非常有用。到底這兩個(gè)函數(shù)是什么意義呢?
map
首先看這個(gè)map,map顧名思義,就是映射,例如我們有一個(gè)數(shù)組,我們想把數(shù)組里面的每一個(gè)數(shù)乘以二。
let arr = [1, 2, 3, 4, 5, 6]
let twoTimesArray = arr.map { $0 * 2 }
twoTimesArray // [2, 4, 6, 8, 10, 12]
從我們方法的定義可以看到,我們可以看到

所以我們這個(gè)數(shù)組是不能是optional的,如果把上面的數(shù)組換成
let arr: [Int?] = [1, 2, 3, 4, 5, 6, nil]
我們就會(huì)報(bào)錯(cuò)了。
flatMap
概念
flatMap的主要作用,是把我們的這個(gè)把我們的多個(gè)集合合為一個(gè)集合。
let nestedArray = [[1, 2, 3], [4, 5, 6]]
let flattenedArray = nestedArray.flatMap{ $0 }
flattenedArray // [1, 2, 3, 4, 5, 6]
那么我們想讓每個(gè)元素乘以2,試著做如下的代碼
let nestedArray = [[1, 2, 3], [4, 5, 6]]
let flattenedArray = nestedArray.flatMap{ $0 * 2}
flattenedArray
什么?!竟然報(bào)錯(cuò)了,報(bào)錯(cuò)信息是這樣的

可以看到,錯(cuò)誤提示了我們,實(shí)際上我們的的flatmap操作的不是數(shù)組中的元素,他操作的是整個(gè)數(shù)組。實(shí)際上,我們可以根據(jù)我們flatMap的定義也可以看到。第一個(gè)是這樣:

可以很清楚的看到,這個(gè)函數(shù)是用來(lái)連接我們的結(jié)果的,所以就是將我們兩個(gè)數(shù)組連接起來(lái)。那么不僅如此,還有一個(gè)函數(shù)定義是這樣的:

這個(gè)函數(shù)是什么意思呢,他是用來(lái)把我們的nil的值去掉的,例如如下的例子
let optionalInts: [Int?] = [1, nil, 2, 3, nil, 4, nil, 5]
let ints = optionalInts.flatMap { $0}
ints // [1, 2, 3, 4, 5]
是把我們的數(shù)組中的nil去除掉,這是flatMap的另外一種用法。這個(gè)也會(huì)是我們開發(fā)中非常有用的一個(gè)功能。實(shí)際上,這兩個(gè)方法是相似的,為什么說(shuō)呢?
剖析
我們可以這么想,如果我們上面的例子,數(shù)組如果變成這種樣子,我們可以得到
let nestedArray = [[],[1, 2, 3]]
let flattenedArray = nestedArray.flatMap{ $0}
flattenedArray // [1, 2, 3]
那么,我們的Optional其實(shí)也是一個(gè)枚舉類型,這個(gè)可以從Swift的API就能看出,我們可以這樣定義一個(gè)Optional.
let a: Optional<Int> = .Some(5)
let b: Optional<Int> = .None
所以我們可以把我們的數(shù)組中的nil看成是這種形式
let arr2: [Optional<Int>] = [.None, .Some(5), .None, .Some(2)]
這樣就很容易理解,這兩個(gè)函數(shù)的機(jī)制實(shí)際是一致的。