使用閉包

使用閉包自定義排序

當(dāng)你開始深入研究集合 (包括數(shù)組,字典袜香,集合set)時(shí),閉包就派上了用場鲫惶。之前蜈首,我們使用數(shù)組的sorted()方法對(duì)數(shù)組進(jìn)行排序。現(xiàn)在我們可以通過閉包,自定義排序欢策。

調(diào)用sorted()來獲得數(shù)組排序后的版本:
let names = ["ZZZZZZ", "BB", "A", "CCCC", "EEEEE"]
names.sorted()
// ["A", "BB", "CCCC", "EEEEE", "ZZZZZZ"]
通過自定義閉包吆寨,可以更改數(shù)組的排序細(xì)節(jié)。定義一個(gè)尾隨閉包踩寇,如下所示:
names.sorted {
  $0.count > $1.count
}
// ["ZZZZZZ", "EEEEE", "CCCC", "BB", "A"]

現(xiàn)在啄清,數(shù)組按字符串的長度排序,字符串的長度優(yōu)先

使用閉包遍歷集合

在Swift中俺孙,集合實(shí)現(xiàn)了一些非常方便的特性辣卒,這些特性通常與函數(shù)式編程相關(guān)聯(lián),這些特性以函數(shù)的形式出現(xiàn)睛榄,可以將這些功能應(yīng)用到集合上荣茫,以對(duì)其執(zhí)行操作。

轉(zhuǎn)換元素

對(duì)集合中的元素進(jìn)行循環(huán)场靴,并執(zhí)行操作:

let values = [1, 2, 3, 4, 5, 6]
values.forEach {
    print("\($0): \($0*$0)")
}

這個(gè)循環(huán)遍歷集合中每個(gè)元素并打印值和值的平方

過濾元素

var prices = [1.5, 10, 4.99, 2.30, 8.19]
let largePrices = prices.filter {
     return $0 > 5
 } 

創(chuàng)建一個(gè)數(shù)組啡莉,表示商店中商品的價(jià)格。過濾大于$5的價(jià)格旨剥,你可以使用filter函數(shù)咧欣。這個(gè)函數(shù)看起來是這樣的:

func filter(_ isIncluded: (Element) -> Bool) -> [Element]

這意味著filter只接受一個(gè)參數(shù),它是一個(gè)閉包(或函數(shù))轨帜,它接受一個(gè)元素并返回一個(gè)Bool魄咕。然后,filter函數(shù)返回一個(gè)元素?cái)?shù)組阵谚。在此上下文中蚕礼,元素指的是數(shù)組中項(xiàng)目的類型。在上面的例子中梢什,元素是Double類型

是否應(yīng)該保留該值,這取決于閉包是返回true或false奠蹬。從filter返回的數(shù)組將包含閉包返回true的所有元素。

在例子中嗡午,largeprice將包含:(10, 8.19)

注意:從filter(以及所有這些函數(shù))返回的數(shù)組是一個(gè)新數(shù)組囤躁。原數(shù)組根本沒有修改。

想象一下荔睹,你正在進(jìn)行一場促銷活動(dòng)狸演,想要把所有的商品都降價(jià)到原來的90%。有一個(gè)很方便的函數(shù)僻他,叫做map宵距,它可以做到這一點(diǎn):

let salePrices = prices.map {
 return $0 * 0.9
}

map函數(shù)接受一個(gè)閉包,在數(shù)組中的每個(gè)條目都會(huì)執(zhí)行它吨拗,并返回一個(gè)包含所有執(zhí)行結(jié)果的新數(shù)組满哪,并保持該順序婿斥。在這種情況下,
salePrices將包含:[1.35, 9, 4.491, 2.07, 7.371]

map函數(shù)可以用來改變類型

let userInput = ["0", "11", "haha", "42"]
let numbers1 = userInput.map {
    Int($0)
 } 

用戶輸入字符串并將它們轉(zhuǎn)換成整數(shù)數(shù)組哨鸭。但是它們需要是可選的民宿,因?yàn)閺膕tring到Int的轉(zhuǎn)換可能會(huì)失敗。

如果你想要過濾掉無效的(丟失的)值像鸡,可以使用flatMap():

let numbers2 = userInput.flatMap {Int($0)} 

flatMap幾乎和map一樣活鹰,只是它創(chuàng)建了一個(gè)Int數(shù)組,并拋出了缺失值只估。

另一個(gè)方便的函數(shù)叫做reduce志群。這個(gè)函數(shù)取一個(gè)起始值和一個(gè)閉包。閉包取兩個(gè)值:當(dāng)前值和數(shù)組中的元素仅乓。閉包的返回值作為當(dāng)前值參數(shù)傳入閉包赖舟。

這可以用于價(jià)格數(shù)組來計(jì)算總數(shù)蓬戚,比如:

let sum = prices.reduce(0) {
 return $0 + $1
}

初始值為0夸楣。然后,閉包計(jì)算當(dāng)前值的和加上當(dāng)前迭代的值子漩。這樣就計(jì)算了數(shù)組中所有值的總和豫喧。在這種情況下,sum將是:
26.98

現(xiàn)在你已經(jīng)知道了filter幢泼、map和reduce紧显,希望能夠清楚地了解這些函數(shù)的強(qiáng)大程度,特別是閉包的語法缕棵。在幾行代碼中孵班,你已經(jīng)可以從集合中計(jì)算相當(dāng)復(fù)雜的值。

這些函數(shù)也可以用于字典招驴。想象一下篙程,你在你的倉庫里用一個(gè)字典來表示你的股票,用這個(gè)價(jià)格映射到商品的數(shù)量上别厘。你可以用它來計(jì)算你的股票的總價(jià)值:

let stock = [1.5: 5, 10: 2, 4.99: 20, 2.30: 5, 8.19: 30]
let stockSum = stock.reduce(0) {
   return $0 + $1.key * Double($1.value)
}

在本例中虱饿,reduce函數(shù)的第二個(gè)參數(shù)是一個(gè)tuple,它包含來自字典元素的鍵和值触趴。計(jì)算值需要類型轉(zhuǎn)換氮发。

結(jié)果是:384.5

還有另一種形式的reduce,當(dāng)你需要將集合變?yōu)閿?shù)組或字典時(shí)冗懦,它是有用的爽冕。它叫做reduce(into:_:)。你可以這樣使用:

let farmAnimals = ["??": 5, "??": 10 ,"??": 50 ,"??": 1]

let allAnimals = farmAnimals.reduce(into: []) { 
(result, this: (key: String, value: Int)) in

  for _ in 0 ..< this.value {
    result.append(this.key)
  }

 } 

它與其他版本的執(zhí)行完全相同披蕉,只是不從閉包返回什么颈畸。相反前塔,每個(gè)迭代都給你一個(gè)可變的值來處理。這樣承冰,在這個(gè)示例中只有一個(gè)數(shù)組被創(chuàng)建并添加元素华弓。。

還有一些不同的功能困乒,在你需要切割的時(shí)候會(huì)很有用寂屏。

dropFirst

let removeFirst = prices.dropFirst()
let removeFirstTwo = prices.dropFirst(2)

dropFirst函數(shù)接受一個(gè)默認(rèn)值為1的參數(shù),并返回一個(gè)數(shù)組娜搂,其中包含從前面刪除的元素迁霎。在這種情況下,結(jié)果如下:

removeFirst = [10, 4.99, 2.30, 8.19]
removeFirstTwo = [4.99, 2.30, 8.19]

就像dropFirst一樣百宇,也存在從數(shù)組末尾移除元素的dropLast考廉。是這樣的:

dropLast

let removeLast = prices.dropLast()
let removeLastTwo = prices.dropLast(2)

這些結(jié)果如你所料,如下:

removeLast = [1.5, 10, 4.99, 2.30]
removeLastTwo = [1.5, 10, 4.99]

可以獲取數(shù)組的第一個(gè)或最后一個(gè)元素携御,如下所示:

let firstTwo = prices.prefix(2)
let lastTwo = prices.suffix(2)

這里昌粤,prefix返回?cái)?shù)組前面的元素,suffix返回 數(shù)組后面的元素啄刹。該函數(shù)的結(jié)果為:

firstTwo = [1.5, 10]
lastTwo = [2.30, 8.19]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涮坐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子誓军,更是在濱河造成了極大的恐慌袱讹,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昵时,死亡現(xiàn)場離奇詭異捷雕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壹甥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門救巷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盹廷,你說我怎么就攤上這事征绸。” “怎么了俄占?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵管怠,是天一觀的道長。 經(jīng)常有香客問我缸榄,道長渤弛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任甚带,我火速辦了婚禮她肯,結(jié)果婚禮上佳头,老公的妹妹穿的比我還像新娘。我一直安慰自己晴氨,他們只是感情好康嘉,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著籽前,像睡著了一般亭珍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枝哄,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天肄梨,我揣著相機(jī)與錄音,去河邊找鬼挠锥。 笑死众羡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蓖租。 我是一名探鬼主播粱侣,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼菜秦!你這毒婦竟也來了甜害?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤球昨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后眨攘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體主慰,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年鲫售,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了共螺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡情竹,死狀恐怖藐不,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秦效,我是刑警寧澤雏蛮,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站阱州,受9級(jí)特大地震影響挑秉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苔货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一犀概、第九天 我趴在偏房一處隱蔽的房頂上張望立哑。 院中可真熱鬧,春花似錦姻灶、人聲如沸铛绰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽至耻。三九已至,卻和暖如春镊叁,著一層夾襖步出監(jiān)牢的瞬間尘颓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工晦譬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疤苹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓敛腌,卻偏偏與公主長得像卧土,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子像樊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,130評(píng)論 0 21
  • 簡介:Groovy中的閉包就是去掉冗長無用代碼的短小的匿名方法尤莺,閉包從函數(shù)式編程的Lambda表達(dá)式(指定了一個(gè)函...
    one_mighty閱讀 459評(píng)論 0 0
  • 智者說,態(tài)度決定你成功的高度和速度生棍。贊同颤霎。追加一句,態(tài)度要配的上你的夢(mèng)想涂滴,否則友酱,屁也不是。 1你夢(mèng)想成為服裝設(shè)計(jì)師...
    風(fēng)習(xí)習(xí)閱讀 163評(píng)論 0 0
  • 文|秋思說財(cái) 未經(jīng)允許 不得轉(zhuǎn)載 在《基金定投你真的了解嗎柔纵?為什么它比一次性投資好缔杉?》一文中,基金定投是在牛市搁料、熊...
    秋思說閱讀 946評(píng)論 2 6
  • 龍生九子郭计,九子各不同霸琴,及至今日,不依賴拼音拣宏,我也認(rèn)不全它們的名字沈贝。 在大理,這個(gè)黃龍玉館給我留下了深刻印象勋乾,是因?yàn)?..
    丹菡閱讀 787評(píng)論 2 5