Swift高階函數(shù)是指可以接受函數(shù)作為參數(shù)或返回函數(shù)的函數(shù)羽峰。高階函數(shù)強(qiáng)調(diào)了函數(shù)的參數(shù)和返回值都可以是函數(shù)類型,這使得函數(shù)能夠被視為可傳遞和可組合的值和運(yùn)算园蝠。
Swift中有多種高階函數(shù)渺蒿,包括map
,filter
彪薛,reduce
茂装,sort
,flatMap
善延,compactMap
等少态。
1. Map
map
是高階函數(shù)中最常用的函數(shù)之一。它接受一個(gè)函數(shù)和一個(gè)數(shù)組易遣,并返回一個(gè)新數(shù)組彼妻,其中每個(gè)元素都是原始數(shù)組中對(duì)應(yīng)元素通過(guò)輸入的函數(shù)轉(zhuǎn)換后得到的結(jié)果。
以下是一個(gè)簡(jiǎn)單示例豆茫,將一個(gè)數(shù)組中的每個(gè)元素加倍:
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled)
// prints [2, 4, 6, 8, 10]
2. Filter
filter
函數(shù)接受一個(gè)函數(shù)和一個(gè)數(shù)組侨歉,并返回一個(gè)新數(shù)組,其中只包含原始數(shù)組中符合條件的元素揩魂。這個(gè)函數(shù)可以用于過(guò)濾數(shù)組中不需要的元素幽邓。
以下是一個(gè)簡(jiǎn)單示例,從一個(gè)字符串?dāng)?shù)組中過(guò)濾出包含大寫字母的字符串:
let words = ["apple", "banana", "CAT", "dog", "EGG"]
let capitalized = words.filter { word in
let pattern = ".*[A-Z]+.*"
let range = word.range(of: pattern, options: .regularExpression)
return range != nil
}
print(capitalized)
// prints ["CAT", "EGG"]
3. Reduce
reduce
函數(shù)接受一個(gè)函數(shù)和一個(gè)數(shù)組火脉,并返回一個(gè)單一的值牵舵,這個(gè)值是通過(guò)使用指定的函數(shù)對(duì)數(shù)組中的所有元素進(jìn)行聚合得到的。這個(gè)函數(shù)可以用于計(jì)算數(shù)組中所有元素的總和或平均值等倦挂。
以下是一個(gè)簡(jiǎn)單示例畸颅,計(jì)算一個(gè)數(shù)組中所有元素的總和:
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0, { $0 + $1 })
print(sum)
// prints 15
上面的例子在reduce
函數(shù)的初始化值參數(shù)中指定了一個(gè)初始值0,reduce
函數(shù)對(duì)該數(shù)組中的所有元素進(jìn)行了求和操作妒峦。reduce
函數(shù)中的第二個(gè)參數(shù)是一個(gè)閉包重斑,用于對(duì)數(shù)組中的每個(gè)元素進(jìn)行操作。
4. Sorted
sorted
函數(shù)接受一個(gè)數(shù)組肯骇,并返回一個(gè)新數(shù)組窥浪,其中所有元素都按照指定的順序排列。這個(gè)函數(shù)可以用于對(duì)數(shù)組中的元素進(jìn)行排序操作笛丙。
以下是一個(gè)簡(jiǎn)單示例漾脂,對(duì)一個(gè)包含人員信息的數(shù)組按照年齡從小到大排序:
let people = [("Alice", 20), ("Bob", 18), ("Charlie", 25), ("David", 22)]
let sortedPeople = people.sorted { (person1, person2) in
return person1.1 < person2.1
}
print(sortedPeople)
// prints [("Bob", 18), ("Alice", 20), ("David", 22), ("Charlie", 25)]
在這個(gè)例子中,我們傳遞了一個(gè)閉包作為sorted
函數(shù)的參數(shù)胚鸯,這個(gè)閉包用于比較元組中的第二個(gè)元素(年齡)骨稿,成升序排列。
5. FlatMap
flatMap
接受一個(gè)數(shù)組姜钳,然后將每個(gè)元素映射為新的數(shù)組坦冠,并將所有結(jié)果組合成一個(gè)單一的數(shù)組。與map不同哥桥,在使用flatMap
時(shí)辙浑,元素可以映射到一個(gè)可選類型的數(shù)組,從而更加靈活拟糕。
以下是一個(gè)簡(jiǎn)單示例判呕,將一個(gè)含有字符串的數(shù)組轉(zhuǎn)換成一個(gè)包含所有單詞的數(shù)組:
let phrases = ["hello world", "goodbye cruel world"]
let words = phrases.flatMap { $0.split(separator: " ") }
print(words)
// prints ["hello", "world", "goodbye", "cruel", "world"]
在這個(gè)例子中,首先使用split
函數(shù)將字符串分割成單詞數(shù)組送滞,然后使用flatMap
將多個(gè)數(shù)組合并為一個(gè)數(shù)組侠草。
6. CompactMap
compactMap
通過(guò)一個(gè)閉包參數(shù)來(lái)轉(zhuǎn)化數(shù)組中的每個(gè)元素,并返回一個(gè)新的數(shù)組犁嗅,其中nil
值會(huì)被過(guò)濾掉边涕。這個(gè)閉包必須返回一個(gè)可選類型值,當(dāng)返回值為nil
時(shí)褂微,元素將被過(guò)濾掉奥吩。
例如:
let items = [1, 2, 3, 4, 5]
let mappedItems = items.map { $0 * 2 }
print(mappedItems)
// prints [2, 4, 6, 8, 10]
let compactMappedItems = items.compactMap { $0 % 2 == 0 ? $0 : nil }
print(compactMappedItems)
// prints [2, 4]
在上面的例子中,我們將數(shù)組中的元素乘以 2 進(jìn)行了映射蕊梧,產(chǎn)生了一個(gè)新的數(shù)組霞赫。然后我們使用compactMap
過(guò)濾掉了奇數(shù)元素,只剩下了偶數(shù)元素 2 和 4肥矢。
One more Thing
Swift高階函數(shù)的另一個(gè)強(qiáng)大之處在于它們可以鏈接在一起形成一個(gè)管道端衰,這被稱為函數(shù)鏈或函數(shù)式編程范式。使用函數(shù)鏈甘改,我們可以通過(guò)將多個(gè)函數(shù)應(yīng)用于同一個(gè)數(shù)組來(lái)生成一個(gè)復(fù)雜的旅东、自定義的操作序列。
以下是一個(gè)簡(jiǎn)單示例十艾,將一個(gè)字符串?dāng)?shù)組中的大寫字母轉(zhuǎn)換為小寫字母抵代,并按字母順序排序:
let words = ["AbC", "deF", "ghi", "JKL"]
let result = words
.map { $0.lowercased() }
.filter { $0.count <= 3 }
.sorted()
print(result)
// prints ["abc", "def", "ghi"]
在這個(gè)例子中,我們調(diào)用了串聯(lián)式的map
忘嫉、filter
和sorted
函數(shù)荤牍,它們?cè)谝黄鹦纬闪艘粋€(gè)管道案腺,每個(gè)函數(shù)都返回一個(gè)新的數(shù)組,以形成復(fù)合操作康吵。
通過(guò)函數(shù)鏈劈榨,我們可以創(chuàng)建與原始數(shù)據(jù)完全不同的結(jié)果,并且所需的代碼量非常少晦嵌。使用高階函數(shù)以及函數(shù)鏈編程方式同辣,可以使代碼更加可讀性強(qiáng),更加易于維護(hù)和測(cè)試惭载。
總之旱函,高階函數(shù)是Swift語(yǔ)言中非常強(qiáng)大和靈活的工具,可以大大簡(jiǎn)化代碼描滔,并提高代碼的可讀性和可維護(hù)性棒妨。掌握這些高階函數(shù),可以讓我們更快地構(gòu)建高效伴挚、簡(jiǎn)潔的代碼靶衍。