【Tips】map & flatMap

前言

在RxSwift中罚屋,map , flatMap兩個(gè)操作符用的比較算是比較頻繁的即碗,開始的時(shí)候?qū)?code>flatMap理解并不是那么深刻男应,下面就一個(gè)例子來說下自己對(duì)于flatMap的認(rèn)識(shí):

 Observable.of(1, 2, nil ,4)
        .flatMap { $0 == nil ? Observable.empty() : Observable.just($0!) }
        .subscribe(onNext: {
            print($0)
        })

開始

其實(shí)說到flatMap,它相對(duì)于map的不同就是所謂的降維;但是如果用降維來解釋如上的栗子配椭,好像并不那么貼切虫溜?

或許是筆者理解不夠透徹,希望讀者可以給出自己的解釋

接著

因?yàn)槔踝又械?code>observable并不是所謂的inner observables股缸;栗子中的輸出結(jié)果是:

1
2
4

如果flatMap 換成map衡楞,輸出結(jié)果如下:

RxSwift.Just<Swift.Int>
RxSwift.Just<Swift.Int>
RxSwift.Empty<Swift.Int>
RxSwift.Just<Swift.Int>

結(jié)果截然不同!所以下面筆者說下自己的理解:
mapflatMap敦姻,兩個(gè)操作符都是將observable中的元素進(jìn)行變換瘾境。map操作符變換后的元素類型就是閉包返回的類型,所以本文栗子中使用map后替劈,訂閱輸出的就是RxSwift.%%類型寄雀;而flatMap閉包返回的類型都是Observable類型得滤,但是變換后的元素是Observable類型中Element的類型陨献,所以栗子中使用flatMap后輸出的依然是 Int類型。
栗子中flatMap閉包每次返回的Observable將其中的element發(fā)送到一個(gè)新的Observable懂更,這個(gè)新的Observable會(huì)被訂閱者所訂閱眨业,這個(gè)新的Observable就可以說明flatMap的降維,也是所謂的flat沮协。

然后

因?yàn)槔踝又凶畛醯?code>Observable中有一個(gè)元素為空龄捡,所以ObservableElement類型應(yīng)該是Optional,但是經(jīng)過flatMap后輸出的卻不是慷暂,說明flatMap可以過濾Observable中為空的element聘殖。
之所以能過濾空的element,主要還是因?yàn)?code>flatMap會(huì)新建一個(gè)Observable行瑞,因?yàn)槔踝又虚]包奸腺,當(dāng)元素為空的時(shí)候返回的是一個(gè)空的Observable,所以新的Observable并不會(huì)接收到其中的element血久,之后訂閱者所輸出的也就不存在空的元素突照,所以類型自然也就不是Optional

Swift中的flatMap氧吐,同樣的也可以過濾空的元素

["ab", "cc", nil, "dd"].flatMap { $0 }
["ab", "cc", nil, "dd"].filter { $0 != nil} .map { $0! }

此時(shí)數(shù)組是["ab", "cc", "dd"],而且不是Optional類型讹蘑,只是使用flatMap更佳簡(jiǎn)潔高效;因?yàn)閮?nèi)部使用了if let,所以達(dá)到了過濾空元素的效果筑舅。

Functor and Monad 更新于2017-12-04

Functor and Monad是函數(shù)式編程的重要概念座慰,筆者之前也不是太理解,只是聽過名稱而已翠拣,其實(shí)他們的定義和map角骤,flatMap關(guān)系很大:

flatMap其實(shí)是一種特殊的map,所謂的降維是因?yàn)閒lat的原因

下面是筆者對(duì)于數(shù)組類型實(shí)現(xiàn)的map, flatten, flattenMap:

extension Array {
    func myMap<T>(_ transform: (Element) -> T) -> [T] {
        var result: [T] = []
        result.reserveCapacity(count)
        for x in self {
            result.append(transform(x))
        }
        return result
    }
    
    func myFlatten<T>(elements: [[T?]]) -> [T] {
        var result: [T] = []
        
        for arr in elements {
            for item in arr {
                if let num = item {
                    result.append(num)
                }
            }
        }

        return result
    }
    
    func myFlattenMap<T>(_ transform: (Element) -> [T?]) -> [T] {
        return myFlatten(elements: myMap(transform))
    }
    
}

根據(jù)上面的代碼,其實(shí)functor和monad的定義也就很容易理解了:

Functor: map 函數(shù)接受一個(gè)閉包作為參數(shù)邦尊,作用與容器類型(數(shù)組背桐,optional,result)蝉揍,通過傳入的閉包改變?nèi)萜黝愋蛢?nèi)部的值链峭,從而得到一個(gè)全新的容器; 所謂functor就是實(shí)現(xiàn)了map功能的類型;

Monad: monad 是functor中的一種又沾,相比functor不僅實(shí)現(xiàn)了map功能弊仪,而且實(shí)現(xiàn)了flattenMap的功能护赊;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萍悴,一起剝皮案震驚了整個(gè)濱河市痊末,隨后出現(xiàn)的幾起案子题画,更是在濱河造成了極大的恐慌帚豪,老刑警劉巖嵌削,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吓歇,死亡現(xiàn)場(chǎng)離奇詭異一铅,居然都是意外死亡表窘,警方通過查閱死者的電腦和手機(jī)典予,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乐严,“玉大人瘤袖,你說我怎么就攤上這事“貉椋” “怎么了捂敌?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)既琴。 經(jīng)常有香客問我占婉,道長(zhǎng),這世上最難降的妖魔是什么呛梆? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任锐涯,我火速辦了婚禮,結(jié)果婚禮上填物,老公的妹妹穿的比我還像新娘纹腌。我一直安慰自己,他們只是感情好滞磺,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布升薯。 她就那樣靜靜地躺著,像睡著了一般击困。 火紅的嫁衣襯著肌膚如雪涎劈。 梳的紋絲不亂的頭發(fā)上广凸,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音蛛枚,去河邊找鬼谅海。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蹦浦,可吹牛的內(nèi)容都是我干的扭吁。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼盲镶,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼侥袜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起溉贿,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤枫吧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后宇色,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體九杂,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年代兵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尼酿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爷狈。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡植影,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涎永,到底是詐尸還是另有隱情思币,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布羡微,位于F島的核電站谷饿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏妈倔。R本人自食惡果不足惜博投,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盯蝴。 院中可真熱鬧毅哗,春花似錦、人聲如沸捧挺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)闽烙。三九已至翅睛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捕发。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工疏旨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扎酷。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓充石,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親霞玄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骤铃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

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

  • 一、數(shù)組中的 map 和 flatMap 數(shù)組中的 map 對(duì)數(shù)組元素進(jìn)行某種規(guī)則的轉(zhuǎn)換坷剧,例如: 二惰爬、 flatM...
    kmplayer閱讀 4,055評(píng)論 0 6
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的惫企,對(duì)什么是操作撕瞧、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,867評(píng)論 0 10
  • http://blog.csdn.net/yyh352091626/article/details/5330472...
    奈何心善閱讀 3,563評(píng)論 0 0
  • 最近在學(xué)習(xí)RxSwift相關(guān)的內(nèi)容,在這里記錄一些基本的知識(shí)點(diǎn)狞尔,以便今后查閱丛版。 Observable 在RxSwi...
    L_Zephyr閱讀 1,762評(píng)論 1 4
  • 前言 按照官方的分類,操作符大致分為以下幾種: Creating Observables(Observable的創(chuàng)...
    小玉1991閱讀 1,052評(píng)論 0 1