lro gro_斯威夫特:Gro吟M

lro gro

Swift borrows many functional programming concepts, among others: map, flatMap and compactMap. This article will give a closer look at these operations.

Swift借鉴了许多函数式编程概念,其中包括mapflatMapcompactMap 。 本文将详细介绍这些操作。

地图 (map)

Suppose that we have detectives with: name, rank and cases working on. To find out which detectives are heavily involved in solving cases we can implement the following approach

假设我们有侦探,他们的名字,职级和案件正在研究中。 为了找出哪些侦探在解决案件中投入大量精力,我们可以采用以下方法

struct Detective {
let name: String
let rank: String
let cases: UInt
}func involvedInCases(detectives: [Detective]) -> [String] {
var involvments = [String]()
for detective in detectives {
let involvment: String;
switch detective.cases {
case 0: involvment = "\(detective.name) is not involved"
case 1...10: involvment = "\(detective.name) is pretty involved"
default: involvment = "\(detective.name) is heavily involved"
}
involvments.append(involvment)
}
return involvments
}

This is a good start, but it can be improved with map operation. With map you can transform each value of the array into something that is desirable. map receives a closure which gets called for each element of the array. After it finishes it returns a new mapped array.

这是一个好的开始,但是可以通过map操作进行改进。 使用map可以将数组的每个值转换为所需的值。 map收到一个闭包,该闭包被数组的每个元素调用。 完成后将返回一个新的映射数组。

func involvedInCases(detectives: [Detective]) -> [String] {
return detectives
.map { detective -> String in
switch detective.cases {
case 0: return "\(detective.name) is not involved"
case 1...10: return "\(detective.name) is pretty involved"
default: return "\(detective.name) is heavily involved"
}
}
}

This looks pretty good, and can be extended even more. The result of map can be put into pipeline to perform additional transformations. Imagine that we need to get the names of detectives who are not involved in any case in order to assign them some. We can accomplish this by creating a following construct:

这看起来不错,并且可以扩展得更多。 可以将map的结果放入管道中以执行其他转换。 想象一下,我们需要获取在任何情况下都没有参与的侦探的姓名,以便为其分配一些侦探的姓名。 我们可以通过创建以下结构来实现:

func getUninvovedDetectivesSorted(detectives: [Detective]) -> [String] {
return detectives
.filter { $0.cases == 0 }
.map { $0.name }
.sorted(by: <)
}

A pipeline defines a clear and immutable way of transforming data into separate steps. Generally, a pipeline is performant enough and worth the expressive and immutable nature.

管道定义了将数据转换为单独步骤的清晰且不变的方式。 通常,管道具有足够的性能,值得具有表达性和不变性。

An Array is not the only collection type which you can use map over. You can use any Collection and Sequence protocol implementation as well as Optionals.

Array不是唯一可以使用map集合类型。 您可以使用任何CollectionSequence协议实现以及Optional

flatMap (flatMap)

The flatMap function is similar to map except that it “flattens” the resulting array. With map you can end up with nested type, flatMap is there to handle this case. The example below shows detective's scores on each test, and we want to check if the average result is higher than some threshold value:

flatMap函数与map相似, flatMap在于它“展平”了结果数组。 使用map您可以使用嵌套类型来结束, flatMap可以处理这种情况。 下面的示例显示了每次测试中侦探的得分,我们要检查平均结果是否高于某个阈值:

let detectiveScoresByName = [
"John": [100, 35, 86],
"Nick": [22, 56, 86],
"Ron": [92, 1, 34]]
let mapped = detectiveScoresByName.map { $0.value }
// [[100, 35, 86], [22, 56, 86], [92, 1, 34]] - An array of arrays
let flatMapped = detectiveScoresByName.flatMap { $0.value }
// [100, 35, 86, 22, 56, 86, 92, 1, 34] - flattened to only one array// implementation of the check omitted

So map transforms an array of values into an array of other values, and flatMap does the same thing, but also flattens the result of nested collections into just a single array.

因此, map将值的数组转换为其他值的数组, flatMap做相同的事情,但还将嵌套集合的结果展平为单个数组。

compactMap (compactMap)

Finally, there’s compactMap, which lets us discard any nil values that our transform might produce. Instead of flattening nested collection, this function performs flattening optionals inside the collection.

最后,还有compactMap ,它使我们可以丢弃转换可能产生的任何nil值。 代替展平嵌套的集合,此函数在展馆内部执行展平可选项。

Let's go over an example that will shine a light on this type of operation. A user is providing a list of his/hers favorite websites, which we are trying to reach from code. We will try to turn passed strings into URLs and then perform operation:

让我们来看一个示例,该示例将阐明这种类型的操作。 用户正在提供他/她最喜欢的网站的列表,我们正在尝试从代码中访问这些列表。 我们将尝试将传递的字符串转换为URL,然后执行操作:

let urls = [
"http://www.google.com",
"http://www.duckduckgo.com",
"http://www.bing.com",
"http://my search engine.com"]
let mapped = urls.map { URL(string: $0) }
// [Optional(http://www.google.com), Optional(http://www.duckduckgo.com), Optional(http://www.bing.com), nil]
let compactMapped = urls.compactMap(URL.init)
// [http://www.google.com, http://www.duckduckgo.com, http://www.bing.com]// implementation of the ping omitted

As construction of URL can fail and return nil, map would not produce correct output (it will contain nil). Additionally, map would produce elements wrapped in Optional which should be handled. compactMap takes care of both problems for us.

由于URL构建可能会失败并返回nil ,因此map不会产生正确的输出(它将包含nil )。 此外, map会产生包装在Optional中的元素,这些元素应进行处理。 compactMap为我们解决了这两个问题。

As for map, both flatMap and compactMap can be chained (used in pipeline).

至于mapflatMapcompactMap都可以链接(在管道中使用)。

重要要点 (Key takeaways)

  • map transforms an array of values into an array of other values

    map将值数组转换为其他值数组

  • flatMap does the same thing, but also flattens the result of nested collections into just a single array

    flatMap做同样的事情,但是也将嵌套集合的结果展平为单个数组

  • when an Optional is nil, map and flatMap will ignore any chained operations

    OptionalnilmapflatMap将忽略任何链接的操作

  • with compactMap you can filter nil values out of arrays and sequences of Optionals

    使用compactMap您可以从Optional的数组和序列中过滤出nil

  • everything can be done in imperative way as well

    一切也可以以命令方式完成
  • if you are considering performance as a key factor, you should test both imperative and functional way in order to tailor the code to your needs

    如果您将性能视为关键因素,则应该同时测试命令式和功能性方式,以便根据需要定制代码

翻译自: https://medium.com/swlh/swift-grokking-map-flatmap-and-compactmap-a675f9c2e4ff

lro gro

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值