Swift數組中Map,FlatMap,Filter,Reduce的使用

Map

map函數能夠被數組調用,它接受一個閉包作為參數,作用于數組中的每個元素。閉包返回一個變換后的元素,接著將所有這些變換后的元素組成一個新的數組

1. 比如我們有一個這樣的需求遍歷一個數組中所有的元素,將每個元素自身與自身相加,最后返回一個保存相加后元素的數組(-_-原諒我這表達能力,下面用代碼闡述)

如果我們不使用map函數,那么代碼如下

let numbers = [1,2,3]
var sumNumbers = [Int]()
for var number in numbers {
    number += number
    sumNumbers.append(number)
}
// [2,4,6]
print(sumNumbers)

可以看到上面的代碼正是我們經常用到的代碼,但通過數組的map函數可以幫我們簡化上面的代碼

// 可以看到我們甚至可以不再定義可變的數組直接用不可變的就可以
let numbers = [1,2,3]
let sumNumbers = numbers.map { (number: Int) -> Int in
    return number + number
}
// 下面介紹簡便寫法 因為map閉包里面的類型可以自動推斷所以可以省略
let sumNumbers1 = numbers.map { number in
    return number + number
}
// 可以省了return 但是循環次數多了一次 目前不知道這是什么原因(循環次數是3次這是4次) 結果是一樣的 <如果哪位大神知道麻煩告明小弟>
let sumNumbers2 = numbers.map { number in number + number }
print(sumNumbers2) // [2,4,6]
// 最終簡化寫法
let sumNumbers3 = numbers.map { $0 + $0 }

2. Map函數返回數組的元素類型不一定要與原數組相同

let fruits = ["apple", "banana", "orange", ""]
// 這里數組中存在一個""的字符串 為了后面來比較 map 和 flatMap
let counts = fruits.map { fruit -> Int? in
    let length = fruit.characters.count
    guard length > 0 else {
        return nil
    }
    return length
}
// [Optional(5), Optional(6), Optional(6), nil]
print(counts)

3. Map還能返回判斷數組中的元素是否滿足某種條件的Bool值數組

let array = [1,2,3,4,5,6]
// 最潔簡的寫法
let isEven = array.map { $0 % 2 == 0 }
// 這里在寫下完成的寫法 下面的例子 將都采用最潔簡的寫法^_^ 同時也要養成習慣看見上面那種潔簡的寫法 就要懂它做了些什么 會有什么樣的結果
let isEven1 = array.map { num in
    // 寫上retrun在Playground中的循環次數是6次 不寫是7次 Xcode版本是7.2(7C68) 
    // 不知道這是不是bug 有知道的提醒下我~
    return num % 2 == 0
}
// [false, true, false, true, false, true]
print(isEven)

FlatMap

flatMap 與 map 不同之處是
flatMap返回后的數組中不存在 nil 同時它會把Optional解包;
flatMap 還能把數組中存有數組的數組 一同打開變成一個新的數組 ;
flatMap也能把兩個不同的數組合并成一個數組 這個合并的數組元素個數是前面兩個數組元素個數的乘積

1. flatMap返回后的數組中不存在nil 同時它會把Optional解包

let fruits = ["apple", "banana", "orange", ""]
let counts = fruits.flatMap { fruit -> Int? in
    let length = fruit.characters.count
    guard length > 0 else {
        return nil
    }
    return length
}
// [5,6,6]
print(counts)

2. flatMap 還能把數組中存有數組的數組 一同打開變成一個新的數組(看代碼秒懂_)

let array = [[1,2,3], [4,5,6], [7,8,9]]
// 如果用map來獲取新的數組
let arrayMap = array.map { $0 }
// [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(arrayMap)
// 用flatMap
let arrayFlatMap = array.flatMap { $0 }
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(arrayFlatMap)

3. flatMap也能把兩個不同的數組合并成一個數組 這個合并的數組元素個數是前面兩個數組元素個數的乘積

// 這種情況是把兩個不同的數組合并成一個數組 這個合并的數組元素個數是前面兩個數組元素個數的乘積
let fruits = ["apple", "banana", "orange"]
let counts = [1, 2, 3]
let fruitCounts = counts.flatMap { count in
    fruits.map { fruit in
//        title + "\(index)"
        // 也可以返回元組
        (fruit, count)
    }
}
// [("apple", 1), ("banana", 1), ("orange", 1), ("apple", 2), ("banana", 2), ("orange", 2), ("apple", 3), ("banana", 3), ("orange", 3)]
print(fruitCounts)
// 這種方法估計用的很少 可以算是一個 flatMap 和 map 的結合使用吧

Filter

filter 可以取出數組中符合條件的元素 重新組成一個新的數組

filter可以很好的幫我們把數組中不需要的值都去掉 這個很贊!

let numbers = [1,2,3,4,5,6]
let evens = numbers.filter { $0 % 2 == 0 }
// [2, 4, 6]
print(evens)

Reduce

map,flatMap和filter方法都是通過一個已存在的數組,生成一個新的、經過修改的數組。然而有時候我們需要把所有元素的值合并成一個新的值 那么就用到了Reduce

1. 比如我們要獲得一個數組中所有元素的和

let numbers = [1,2,3,4,5]
// reduce 函數第一個參數是返回值的初始化值
let sum = numbers.reduce(0) { $0 + $1 }
// 這里我寫下完整的格式
let sum1 = numbers.reduce(0) { total, num in
    // 這里寫不寫return在Playground都循環5次 但上面用最潔簡的方法顯示循環6次。。。 What The Fuck 這是什么鬼!!!
    return total + num
}
// 15
print(sum)

2. 合并成的新值不一定跟原數組中元素的類型相同

let numbers = [1,5,1,8,8,8,8,8,8,8,8]
// reduce 函數第一個參數是返回值的初始化值
let tel = numbers.reduce("") { "\($0)" + "\($1)" }
// 15188888888
print(tel)

3. ruduce 還可以實現 map 和 filter 并且時間復雜度變為O(n) 原來 map 和 filter 的時間復雜度是O(n*n)

extension Array {
    func mMap<U> (transform: Element -> U) -> [U] {
        return reduce([], combine: { $0 + [transform($1)] })
    }
    func mFilter (includeElement: Element -> Bool) -> [Element] {
        return reduce([]) { includeElement($1) ? $0 + [$1] : $0 }
    }
}

本人對泛型的研究還很淺顯,后續我會寫一篇關于Swift范型的文章,歡迎大家關注 -> MelodyZhy

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,520評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372

推薦閱讀更多精彩內容