随笔 - 400,  文章 - 0,  评论 - 7,  阅读 - 21万

 

Swift - 高阶函数介绍(map、flatMap、filter、reduce、zip)

 

map

复制代码
在 Swift 中,map 是一个高阶函数,它通常用于对集合中的每个元素进行转换操作,并返回一个新的集合。map 函数可以应用于数组、字典、集合等类型。

基本语法
对于 数组(Array) 来说,map 的基本语法如下:

swift
let newArray = oldArray.map { element in
    // 对元素进行处理并返回结果
    return transformedElement
}
oldArray 是你要操作的原始数组。
element 是数组中的每个元素。
transformedElement 是你对每个元素进行转换后得到的新的元素。
newArray 是转换后的新数组,它的元素类型可能与原数组不同。
示例
1. 基本的 map 用法(数组)
假设我们有一个整数数组,我们想要将每个元素乘以 2:

swift
let numbers = [1, 2, 3, 4, 5]
let doubledNumbers = numbers.map { \$0 * 2 }

print(doubledNumbers)  // 输出: [2, 4, 6, 8, 10]
在这个例子中,\$0 代表数组中的每个元素,\$0 * 2 对每个元素进行变换并返回新的数组。

2. 通过 map 将字符串数组转换为大写字母
swift
let words = ["apple", "banana", "cherry"]
let uppercaseWords = words.map { \$0.uppercased() }

print(uppercaseWords)  // 输出: ["APPLE", "BANANA", "CHERRY"]
这里,map 将每个字符串转换为其大写形式。

3. 转换为其他类型(将数组的数字转换为字符串)
swift
let numbers = [1, 2, 3, 4, 5]
let stringNumbers = numbers.map { String(\$0) }

print(stringNumbers)  // 输出: ["1", "2", "3", "4", "5"]
这里,map 把每个数字转换成了字符串。

4. map 与字典(Dictionary)配合使用
对于字典,map 会遍历字典的所有值,并返回一个新的字典或数组。

例如,下面是一个将字典中的值进行转换的例子:

swift
let dictionary = ["a": 1, "b": 2, "c": 3]
let valuesSquared = dictionary.map { (key, value) in
    return value * value
}

print(valuesSquared)  // 输出: [1, 4, 9]
在这个例子中,我们将字典中的每个值(value)进行了平方处理,并返回了一个包含平方值的新数组。

5. map 与 Optional 配合使用
map 也可以用来处理 Optional 类型。对于 Optional 类型,map 可以用来将其包含的值进行变换。

例如:

swift
let optionalNumber: Int? = 5
let doubledNumber = optionalNumber.map { \$0 * 2 }

print(doubledNumber)  // 输出: Optional(10)
这里,map 将 optionalNumber 内的值乘以 2,并返回一个新的 Optional 值。如果原始值为 nil,则返回的结果也会是 nil。

6. 对 Optional 的数组使用 map
对于一个包含 Optional 的数组,可以使用 map 来对其进行解包(即将 Optional 转换为普通值),或者进行其他操作:

swift
let optionalNumbers: [Int?] = [1, nil, 3, 4, nil]
let unwrappedNumbers = optionalNumbers.compactMap { \$0 }  // 使用 compactMap 来过滤掉 nil 值

print(unwrappedNumbers)  // 输出: [1, 3, 4]
compactMap 是 map 的变种,它会在映射的过程中自动去除 nil 值,并返回一个非 Optional 类型的数组。

总结
map 是一种非常强大的函数式编程工具,可以用于转换集合中的元素。
它会遍历整个集合,对每个元素应用一个转换闭包,并返回一个包含转换结果的新集合。
map 常用于数组、字典和 Optional 类型的转换。
对于 Optional 类型,map 可以用来对值进行转换,如果值为 nil,则返回 nil。
map 使得你可以以更简洁的方式进行数据处理,避免了冗长的循环或条件判断。
复制代码

 

 

flatMap

 

复制代码
在 Swift 中,flatMap 是一个高阶函数,它类似于 map,但有一个重要的区别:flatMap 不仅对每个元素应用转换函数,还会扁平化返回的结果,尤其在处理 Optional 或嵌套集合时非常有用。

基本语法
对于 数组(Array) 来说,flatMap 的基本语法如下:

swift
let newArray = oldArray.flatMap { element in
    // 对元素进行处理并返回一个集合(可能是数组、可选类型等)
    return transformedElement
}
flatMap 会“扁平化”这些集合(例如,数组数组变成了一个扁平的数组),而不像 map 那样直接返回一个包含集合的数组。

示例
1. 数组的 flatMap
假设我们有一个数组,其中的每个元素都是一个数组,我们想要将其“扁平化”,得到一个单一的数组。

swift
let numbers = [[1, 2], [3, 4], [5, 6]]
let flattened = numbers.flatMap { \$0 }

print(flattened)  // 输出: [1, 2, 3, 4, 5, 6]
在这个例子中,flatMap 会将每个子数组展平,最终返回一个包含所有元素的单一数组。

2. 处理 Optional 类型的 flatMap
flatMap 也常用于处理 Optional 类型。在 Optional 类型上,flatMap 会在进行转换时,如果原始值为 nil,则返回 nil,否则继续执行转换并返回一个新的 Optional 值。

swift
let number: Int? = 5
let result = number.flatMap { \$0 * 2 }

print(result)  // 输出: Optional(10)
当处理 Optional 时,flatMap 会“扁平化”转换后的 Optional,使得不需要再嵌套 Optional。

3. 数组与 Optional 结合使用
假设我们有一个包含 Optional 元素的数组,想要移除所有的 nil 值,并将剩余的元素进行某种转换。

swift
let numbers: [Int?] = [1, nil, 3, 4, nil]
let doubledNumbers = numbers.flatMap { \$0.map { \$0 * 2 } }

print(doubledNumbers)  // 输出: [2, 6, 8]
这里,flatMap 会首先扁平化 Optional 值,并对每个非 nil 元素执行乘以 2 的操作。通过 flatMap,我们避免了直接使用 filter 或 compactMap 来手动去除 nil 值。

4. 使用 flatMap 与字典
在字典(Dictionary)中,flatMap 会遍历字典的所有键值对,将每个元素转换成一个新的集合,然后将所有这些集合“扁平化”成一个单一集合。

swift
let dictionary = ["a": [1, 2], "b": [3, 4], "c": [5, 6]]
let flattenedValues = dictionary.flatMap { \$0.value }

print(flattenedValues)  // 输出: [1, 2, 3, 4, 5, 6]
在这个例子中,flatMap 将字典中的每个数组(value)都展平,最终返回一个包含所有元素的单一数组。

flatMap 与 map 的区别
map 会对集合中的每个元素应用一个闭包,返回一个新集合,其中每个元素仍然是原来元素的一个“映射”。
flatMap 除了会对每个元素应用转换外,还会扁平化这些转换后的结果,尤其是在返回的是集合类型(例如数组)时。
简而言之:

使用 map 时,结果是一个包含集合的集合。
使用 flatMap 时,结果是一个扁平化的集合。
使用 compactMap 和 flatMap 的比较
compactMap 是 map 的一个变种,它会自动去除 nil 值,返回非 Optional 类型的集合。
flatMap 可以用于各种集合类型,尤其在处理嵌套集合或 Optional 时,能够“扁平化”结果,避免了不必要的嵌套。
总结
flatMap 用于扁平化处理,尤其适用于嵌套的数组、Optional 或其他集合类型。
它将每个元素映射到一个新的集合,并把所有结果合并成一个单一的集合。
对于 Optional 类型,flatMap 在映射过程中,如果遇到 nil 值,会自动返回 nil,避免了 Optional 的嵌套。
通过 flatMap,你可以更方便地处理和转换包含嵌套数据的情况。
复制代码

 

 

filter

复制代码
在 Swift 中,filter 是一个非常有用的高阶函数,它用于对集合中的元素进行筛选,根据给定的条件返回符合条件的元素组成的新集合。与 map 不同,filter 不会改变元素,只会返回符合条件的元素。

filter 函数的基本语法
filter 函数的基本语法如下:

swift
let filteredArray = array.filter { element in
    // 返回 true 或 false,用于判断元素是否满足条件
}
array 是要过滤的集合(可以是数组、字典、集合等)。
{ element in } 是一个闭包,element 表示集合中的每个元素。
闭包返回一个布尔值(truefalse),如果返回 true,则该元素会被包含在返回的新集合中;如果返回 false,则该元素会被排除。
示例:使用 filter 过滤数组
1. 过滤数组中的偶数
swift
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let evenNumbers = numbers.filter { \$0 % 2 == 0 }

print(evenNumbers)  // 输出: [2, 4, 6, 8, 10]
在这个例子中,filter 筛选出数组中所有偶数,返回一个新数组。

2. 过滤数组中的大于 5 的数字
swift
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let greaterThanFive = numbers.filter { \$0 > 5 }

print(greaterThanFive)  // 输出: [6, 7, 8, 9, 10]
filter 函数根据条件 \$0 > 5 过滤出大于 5 的数字。

3. 过滤字符串数组,保留长度大于 3 的字符串
swift
let words = ["apple", "dog", "banana", "cat", "elephant"]
let longWords = words.filter { \$0.count > 3 }

print(longWords)  // 输出: ["apple", "banana", "elephant"]
这里,我们使用 filter 来筛选出长度大于 3 的单词。

示例:使用 filter 过滤字典
对于字典类型的数据,filter 会作用于字典的键值对,返回一个新的字典。需要注意的是,filter 本身并不能直接修改字典,它返回的是一个符合条件的键值对的新集合。

4. 过滤字典中的键值对
swift
let fruitPrices = ["apple": 1.5, "banana": 0.5, "cherry": 2.0, "date": 3.0]
let expensiveFruits = fruitPrices.filter { \$0.value > 1.0 }

print(expensiveFruits)  // 输出: ["apple": 1.5, "cherry": 2.0, "date": 3.0]
在这个例子中,我们通过 filter 函数筛选出价格大于 1.0 的水果。

filter 与 compactMap 的区别
虽然 filter 和 compactMap 都能用来筛选集合,但它们的作用和用途是不同的:

filter 用于根据条件筛选集合中的元素,返回一个新集合,且不改变元素本身。
compactMap 用于移除集合中的 nil 值,并可以将每个元素转换成新的类型,返回的是一个不包含 nil 值的新集合。
filter 与 map 的区别
map 会对集合中的每个元素应用给定的闭包,返回一个新的集合,其中包含每个元素的转换结果。
filter 会根据条件判断筛选集合中的元素,返回一个新集合,只有满足条件的元素会被包含在内。
总结
filter 是一个高阶函数,用于根据给定的条件对集合中的元素进行筛选。
filter 返回的是一个新集合,只有满足条件的元素会被保留。
它适用于数组、字典、集合等各种类型的集合。
filter 是 Swift 中处理集合中元素的强大工具,能够帮助你轻松地从集合中提取出符合某些特定条件的元素。
复制代码

 

 

reduce

复制代码
在 Swift 中,reduce 是一个非常强大的高阶函数,用于将集合中的所有元素结合起来,生成一个单一的值。reduce 函数接受一个初始值和一个闭包,并遍历集合中的元素,将它们逐步合并成一个最终的值。

reduce 函数的基本语法
swift
let result = collection.reduce(initialValue) { accumulator, element in
    // 根据 accumulator 和 element 来生成新的 accumulator
}
initialValue 是初始值,reduce 会从这个值开始。
accumulator 是累加器(即逐步生成最终结果的值),它是从初始值开始的,并且在每次迭代中被更新。
element 是集合中的每个元素。
闭包的返回值将成为新的累加器值,直到遍历完所有元素,最终返回累加器的最终结果。
示例:使用 reduce 对数组进行求和
swift
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { accumulator, element in
    return accumulator + element
}

print(sum)  // 输出: 15
在这个例子中,reduce 的初始值是 0,每次将数组中的元素与累加器相加,最终返回数组元素的总和。

示例:使用 reduce 计算数组中的乘积
swift
let numbers = [1, 2, 3, 4, 5]
let product = numbers.reduce(1) { accumulator, element in
    return accumulator * element
}

print(product)  // 输出: 120
在这个例子中,reduce 从 1 开始,将数组中的每个元素相乘,最终得到数组元素的乘积。

示例:将字符串数组合并为一个字符串
swift
let words = ["Swift", "is", "awesome"]
let sentence = words.reduce("") { accumulator, word in
    return accumulator + " " + word
}

print(sentence)  // 输出: " Swift is awesome"
在这个例子中,reduce 将字符串数组中的每个元素合并成一个完整的句子。

reduce 与 map 和 filter 的区别
map 用于将集合中的每个元素转换为新的元素,返回一个新集合。
filter 用于根据条件筛选集合中的元素,返回一个新集合。
reduce 用于将集合中的元素归并成一个单一的结果。
使用 reduce 对字典进行操作
虽然 reduce 主要用于处理数组,但它也可以用于字典。假设我们想要计算字典中所有值的总和,下面是一个例子:

swift
let prices = ["apple": 1.5, "banana": 0.5, "cherry": 2.0]
let totalPrice = prices.reduce(0) { accumulator, pair in
    return accumulator + pair.value
}

print(totalPrice)  // 输出: 4.0
在这个例子中,reduce 遍历字典的每一个键值对,并将值相加,最终返回所有值的总和。

示例:使用 reduce 计算最长字符串
swift
let words = ["apple", "banana", "cherry", "date"]
let longestWord = words.reduce("") { (longest, current) in
    return current.count > longest.count ? current : longest
}

print(longestWord)  // 输出: "banana"
在这个例子中,我们通过 reduce 找到了数组中最长的字符串。

总结
reduce 是一种用于将集合中的所有元素合并成一个单一结果的工具。
它接受一个初始值和一个闭包,闭包会依次作用于每个元素,并将结果累积起来。
reduce 可以用于数组、字典等各种集合类型,能够用于各种合并、计算和汇总任务。
reduce 是 Swift 中处理数据聚合的一个非常有用的工具,它通过对每个元素的逐步操作,可以帮助你实现许多不同类型的计算和聚合操作。
复制代码

 

zip

复制代码
zip(titleArr, zip(markArr, imageArr)) 是一个 Swift 中非常实用的语法,主要用于将多个数组(或其他序列)合并成一个新的、组合了多个元素的序列。它的工作方式可以用“压缩”来形容,zip 操作会将多个序列按顺序“配对”,生成一个新的序列,其中每个元素都是一个元组,包含来自每个原始序列的对应元素。

示例:
假设我们有以下数组:

swift
let titleArr = ["Title1", "Title2", "Title3"]
let markArr = ["Mark1", "Mark2", "Mark3"]
let imageArr = ["Image1", "Image2", "Image3"]
那么,zip(titleArr, zip(markArr, imageArr)) 的效果是:

swift
[
    ("Title1", ("Mark1", "Image1")),
    ("Title2", ("Mark2", "Image2")),
    ("Title3", ("Mark3", "Image3"))
]
可以看到,zip 会将两个数组按顺序合并成三元组。具体来说:

第一个三元组是 ("Title1", ("Mark1", "Image1"))
第二个三元组是 ("Title2", ("Mark2", "Image2"))
第三个三元组是 ("Title3", ("Mark3", "Image3"))
zip 的使用场景:
zip 非常适合用于需要将多个数组(或其他序列)按元素位置进行配对或组合的场景。例如,合并用户信息(名字、邮箱、头像等),或处理需要按顺序配对的数据。
复制代码

 

posted on   懂事长qingzZ  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示