(原創(chuàng))Swift 高級函數(shù)(sorted/map/flatMap/compactMap/filer/reduce)的使用

一. 常見的高級函數(shù)簡述

函數(shù) 函數(shù)用途 說明
sorted 排序 常用于數(shù)組和字典(key/value)的排序
map 遍歷 每一個元素做一次映射操作
flatMap 遍歷 多于用于數(shù)組的降維度
compactMap 遍歷 多用于處理數(shù)組的可選值
filer 過濾 對數(shù)組元素根據(jù)規(guī)則過濾一次
reduce 多用途 基礎(chǔ)思想是將一個序列轉(zhuǎn)換為一個不同類型的數(shù)據(jù)床牧,期間通過一個累加器(Accumulator)來持續(xù)記錄遞增狀態(tài)

二. 關(guān)于閉包的簡化

1. 閉包的完整格式
   { (parameters) -> return type in    // 閉包的參數(shù)和返回類型
       statements                     // 閉包體
   }

2. 閉包簡寫的依據(jù)

  1. 尾隨閉包的用法
  • 如果最后一個參數(shù)是閉包茶鹃,可以把閉包放()外面
  • 如果該閉包參數(shù)是唯一的參數(shù)懂缕,那么()可以省略
  1. 閉包的隱式返回
    閉包體只有一條執(zhí)行語句,可以省略return
  2. 閉包可根據(jù)上下文推斷參數(shù)和返回值類型
    在閉包中壁涎,因為包含了上下文的變量和常量的引用,并做了類型推斷
  3. 簡化閉包的參數(shù)
    Swift自動為內(nèi)聯(lián)閉包提供簡寫參數(shù)名稱钢悲,用$0(從0開始焕阿,表示第i個參數(shù)...)
例子說明
        let arr = [2, 1, 3]
        /// 完整的sorted的寫法
        let result = arr.sorted (by: { (a: Int, b: Int) -> Bool in
            return a < b
        })
        // 如果傳入的參數(shù),最后一個參數(shù)是閉包坷随,那么可以把閉包放在()外面
        let _ = arr.sorted() { (a: Int, b: Int) -> Bool in
            return a < b
        }
        // 如果傳入的參數(shù)只有一個房铭,且是一個閉包,那么這個()可以省略
        let _ = arr.sorted { (a: Int, b: Int) -> Bool in
            return a < b
        }
        // 從單行表達(dá)式閉包中隱式返回(閉包體只有一行代碼温眉,可以省略return)
        let _ = arr.sorted { (a: Int, b: Int) -> Bool in
            a < b
        }
        // 閉包可更具上下文推斷參數(shù)和返回值的類型
        let _ = arr.sorted { (a, b) -> Bool in
            a < b
        }
        // 簡化閉包的參數(shù)名.使用簡化參數(shù)名缸匪,in和之前的描述可以省略
        let _ = arr.sorted {
            $0 < $1
        }

三. sorted函數(shù)

常用于數(shù)組或者字典的排序操作。

  1. 數(shù)組的操作
        let arr = [2, 1, 3]
        /// 數(shù)組降序排序
        let result = arr.sorted { (a, b) -> Bool in
            return a < b
        }
        /// 數(shù)組升序排序
        let result1 = arr.sorted { (a, b) -> Bool in
            return a > b
        }
  1. 字典的操作
        let dict = [
            "2": "b",
            "1": "a",
            "3": "c",
        ]
        /// 字典key排序
        let result2 = dict.sorted { (a, b) -> Bool in
            return a.key < b.key
        }
        /// 字典value排序
        let result3 = dict.sorted { (a, b) -> Bool in
            return a.value < b.value
        }
  1. sorted函數(shù)的簡化
        // 默認(rèn)從小到大排序
        let _ = arr.sorted()
        // 從小到大排序
        let _ = arr.sorted(by: <)
        // 從大到小排序
        let _ = arr.sorted(by: >)

四. map函數(shù)

map: 映射

1. 說明
  • 可以對數(shù)組中的每一個元素做一次映射操作类溢。
  • map函數(shù)返回一個新的數(shù)組凌蔬,并且數(shù)組的類型不要求和原數(shù)組類型一致。
2. 示例
  • 對數(shù)組的每一個元素都乘以2一次.
let arr = [1,2,3]
let doubleD = arr.map {   
    $0 * 2
}
doubleD的結(jié)果為 : [2, 4, 6]
  • 獲取的數(shù)組類型跟入?yún)?shù)組類型無關(guān)
let mapArr = ["Swift","Objc","Flutter"] 
let mapEndArr = mapArr.map {
    $0.count
}
mapEndArr的結(jié)果為: [5, 4, 7]
  • 返回值中允許nil的存在
let opArr = ["1","2",nil,"3"]
let opMapArr = opArr.map {
    $0
}
opMapArr結(jié)果為: [Optional("1"), Optional("2"), nil, Optional("3")]

五. flatMap 函數(shù)

flat: 使變平

1. flatMap還能把數(shù)組中存有數(shù)組的數(shù)組(二維數(shù)組闯冷、N維數(shù)組)一同打開變成一個新的數(shù)組
        let arr3 = [[1, 2, 3], [4, 5, 6]]
        let result = arr3.flatMap {
            $0
        }
        
        let result2 = arr3.flatMap {
            $0.map {
                $0 + 2
            }
        }
        result的值: [1, 2, 3, 4, 5, 6]
        result2的值: [3, 4, 5, 6, 7, 8]
2. flatMap也能把兩個不同的數(shù)組合并成一個數(shù)組砂心,這個合并的數(shù)組元素個數(shù)是前面兩個數(shù)組元素個數(shù)的乘積
let fruits = ["Apple", "Orange", "Puple"]
let counts = [2, 3, 5]

let array = counts.flatMap { count in
    fruits.map ({ fruit in
        return fruit + "  \(count)"
    })
}
array的結(jié)果 ["Apple 2", "Orange 2", "Puple 2", "Apple 3", "Orange 3", "Puple 3", "Apple 5", "Orange 5", "Puple 5"]

六. compactMap函數(shù)

compact: 把……壓實(shí);使簡潔蛇耀;使緊密辩诞,壓縮

compactMap,可以把一個集合中的空值去除纺涤,并且返回一個去除nil值得數(shù)組
  • 過濾
        // 過濾nil译暂,并解包返回值
        let arr = [1, 5, nil, 4]
        let result = arr.compactMap {
            $0
        }
        // arr的結(jié)果:[1, 5, 4]
  • 類型轉(zhuǎn)換
        // 類型轉(zhuǎn)換 [Int] -> [String]
        let arr1 = [1, 5, 4]
        let result1 = arr1.compactMap {
            String($0)
        }
        // arr1的結(jié)果:["1",  "5", "4"]
  • 篩選數(shù)據(jù)
        let arr3 = [1, 2, 3, 4, 5, 6, 7, 8]
        let result3 = arr3.compactMap {
            $0 % 4 == 0 ? $0 : nil
        }
        //arr3結(jié)果: [4, 8]

結(jié)果可以看出,雖然閉包的返回值是可選的撩炊,但是這個函數(shù)的返回值結(jié)果并不是可選的外永。

七. filer函數(shù)

file: 提出;銼拧咳;琢磨伯顶;把…歸檔。 filer: 銼磨工人

filer過濾函數(shù),可以過濾掉數(shù)組中不滿足篩選條件的元素砾淌,返回滿足篩選條件的元素所組成的數(shù)組啦撮。

  • 篩選出元素 大于 3的元素,并返回集合
        let arr = [1, 2, 3, 4, 5]
        let result = arr.filter {
            $0 > 3
        }
        // result的結(jié)果: [4, 5]
  • 篩選出字符串的長度小于10的字符串
        let arr2 = ["Objective-C", "Swift", "HTML", "CSS", "JavaScript"]

        let result2 = arr2.filter {
            $0.count < 10
        }
        // result的結(jié)果 ["Swift", "HTML", "CSS"]
  • 換種寫法
       // 定義篩選規(guī)則函數(shù)
       func stringCountLessTen(str: String) -> Bool {
           return str.count < 10
       }
       let result2 = arr2.filter(stringCountLessTen(str:))

八. reduce 函數(shù)


func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result

initialResult 為初始值汪厨,Element是要處理的元素赃春,處理后返回Result作為下次閉包的參數(shù)。

  • reduce 的基礎(chǔ)思想是將一個序列轉(zhuǎn)換為一個不同類型的數(shù)據(jù),期間通過一個累加器(Accumulator)來持續(xù)記錄遞增狀態(tài)骡和。為了實(shí)現(xiàn)這個方法笆呆,我們會向 reduce 方法中傳入一個用于處理序列中每個元素的結(jié)合(Combinator)閉包 / 函數(shù) / 方法
  • reduce 是 map狭吼、flatMap 或 filter 的一種擴(kuò)展的形式(后三個函數(shù)能干嘛,reduce 就能用另外一種方式實(shí)現(xiàn))
  1. 獲取數(shù)組中最小的值
        let arr = [1, 4, 3, 2]
        // 獲取數(shù)組中的最小值
        let result = arr.reduce(Int.max, min)
        func combinator(accumulator: Int, current: Int) -> Int {
             return accumulator + current
        }
        [1, 2, 3].reduce(0, combine: combinator)
        // 執(zhí)行步驟如下 
        combinator(0, 1) { return 0 + 1 } = 1
        combinator(1, 2) { return 1 + 2 } = 3
        combinator(3, 3) { return 3 + 3 } = 6
        結(jié)果為 6

        [1,2,3] 中的每個元素都將調(diào)用一次結(jié)合(Combinator)函數(shù)進(jìn)行處理殖妇。同時我們使用累加器(Accumulator)變量實(shí)時記錄遞增狀態(tài)(遞增并非是指加法)刁笙,這里是一個整型值。
  1. 計算數(shù)組元素的加減乘除
        let arr = [1, 4, 3, 2]
        let result2 = arr.reduce(0, +)
        let result3 = arr.reduce(0, -)
        let result4 = arr.reduce(1, *)
        let result5 = arr.reduce(1, /)
        // 分別為 10 -10 24 0
  1. 倒敘數(shù)組
        let arr = [1, 4, 3, 2]
        let result6 = arr.reduce([Int]()) {
            [$1] + $0
        }
        // [2, 3, 4, 1]
  1. 多維度的數(shù)據(jù)處理
        // 計算出位于臺灣省的人數(shù)谦趣,以及平均年齡
        let users: [[String: Any]] = [
            ["name": "小明", "pro": "山東", "age": 10],
            ["name": "小花", "pro": "上海", "age": 30],
            ["name": "小任", "pro": "臺灣", "age": 5],
            ["name": "小愛", "pro": "臺灣", "age": 5],
            ["name": "小李", "age": 10]  // 沒有錄入省份
        ]
        // 定義一個別名為ProvinceTuples元組疲吸,記錄位于臺灣省的人數(shù)(count)和 總年齡(age)
        typealias ProvinceTuples = (count: Int, age: Int)
        
        let result = users.reduce((0, 0)) { (province: ProvinceTuples, user) -> ProvinceTuples in
                        
            // 滿足條件 (能獲取到年齡, 能獲取到省并且省是臺灣)
            // Swift3時if let和guard場景的where已經(jīng)被Swift4的逗號取代
            if let pro = user["pro"] as? String, pro == "臺灣",
                let age = user["age"] as? Int
            {
                return (count: province.count + 1, age: province.age + age)
            } else { // 不滿足條件
                // 此時的province為(0前鹅, 0)
                return province 
            }
        }
        let count = result.0
        let age = Float(result.1) / Float(count)
        // count 為2摘悴, age為5.0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舰绘,隨后出現(xiàn)的幾起案子蹂喻,更是在濱河造成了極大的恐慌,老刑警劉巖捂寿,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件口四,死亡現(xiàn)場離奇詭異,居然都是意外死亡者蠕,警方通過查閱死者的電腦和手機(jī)窃祝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踱侣,“玉大人粪小,你說我怎么就攤上這事÷站洌” “怎么了探膊?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長待榔。 經(jīng)常有香客問我逞壁,道長流济,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任腌闯,我火速辦了婚禮绳瘟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘姿骏。我一直安慰自己糖声,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布分瘦。 她就那樣靜靜地躺著蘸泻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘲玫。 梳的紋絲不亂的頭發(fā)上悦施,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音去团,去河邊找鬼抡诞。 笑死,一個胖子當(dāng)著我的面吹牛渗勘,可吹牛的內(nèi)容都是我干的沐绒。 我是一名探鬼主播俩莽,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼旺坠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扮超?” 一聲冷哼從身側(cè)響起取刃,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎出刷,沒想到半個月后璧疗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馁龟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年崩侠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坷檩。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡却音,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矢炼,到底是詐尸還是另有隱情系瓢,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布句灌,位于F島的核電站夷陋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜骗绕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一藐窄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酬土,春花似錦枷邪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至腹泌,卻和暖如春嘶卧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凉袱。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工芥吟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人专甩。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓钟鸵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涤躲。 傳聞我的和親對象是個殘疾皇子棺耍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 一、數(shù)組中的 map 和 flatMap 數(shù)組中的 map 對數(shù)組元素進(jìn)行某種規(guī)則的轉(zhuǎn)換种樱,例如: 二蒙袍、 flatM...
    kmplayer閱讀 4,003評論 0 6
  • Swift函數(shù)式編程之Map&Reduce&Filter 什么是函數(shù)式編程呢?函數(shù)式編程其實(shí)是一種編程思想, 代碼...
    TitanCoder閱讀 671評論 0 3
  • 一、元祖(Tuples) Tuples have types(元祖有類型)1.它是強(qiáng)類型的嫩挤。這意味著你不能改變一個...
    Mg明明就是你閱讀 421評論 8 6
  • 【陪伴成長】親子共讀20170428 D21 星期五 又到星期五啦害幅,我們仨都有點(diǎn)小激動,特別是我岂昭。不過以现,這...
    珍承鈺閱讀 256評論 0 0
  • 兩人并肩走在公園大道的一邊。 “剛剛你望著窗外出神约啊,在想什么邑遏?”孟書問道。 清音抬起頭淡淡望了他一眼棍苹,嘴角挑起了一...
    a48d4bdef9d1閱讀 160評論 0 1