程序 = 算法 + 数据结构。Swift 的标准库实现了三种通用的数据结构:Array,Set,Dictionary,使用与这些集合相匹配的 sort
,map
, fliter
等多个算法函数,能够使得代码更加简洁,易读,而且性能更好,也成为了 Swift 最强大特性之一。今年更是发布了一个 Swift 算法和集合的开源包,在其中更新了更多的算法函数和数据结构。本文基于 Session 10256[1] 梳理,文章简单介绍其中一些算法和数据结构。需要提前了解的有:
到目前为止,开源包里的算法可以分为以下几个大类:
具体用法和效果可查阅开源地址:Swift Algorithms[4]。下面是算法列表的截图:
下面列举几个 session 里印象比较深刻,或者平时业务开发可能使用得上的方法。
根据 chunks
函数的参数,当前元素与前一个元素“不同”时,这时候就需要分块。比如前后元素的某个值不相等:
或者是元素的类型不同:
而当分块的参数可以是是块大小,此时就会出现“余数”块的情况:
在 seesion 中,假设了有一个消息的列表。现在需要将信息列表根据每一个小时进行分割,并显示对应的时间戳信息。下图就是实现的算法链:
wwdc2021-10256_hd-0015.png
windows(ofCount:)
窗口算法,会以窗口的形式遍历和输出:
wwdc2021-10256_hd-0016.png
windows(ofCount: 2)
的操作特别常用,所以苹果工程师专门为它提供了一个便利方法 adjacentPairs
,而它的返回值是一个元组(而不是一个序列),这样让元素的访问变得更加方便。
wwdc2021-10256_hd-0017.png
compactMap
方法用来过滤集合中的 nils 并映射到解包之后结果集合。compactMap
方法是 filter
和 map
两个方法的合体,其中 filter
方法筛选符合条件的元素集合,map
是映射出一个新的集合。
上面图中的代码等同于
messages
.filter { $0.attachment != nil }
.map { $0.attachment! }
业务场景:图片列表按从新到旧排列,最大个数为 6 个
FlatMap
将集合中的元素都映射到单层的集合中。
上面图中的代码等同于
messages
.map { $0.makeMessageParts() }
.joined()
在下图中的注释会发现 join
方法并没有返回预期中的 [TransriptItem]
数组,而是返回了一个 FlattenSequence 类型:
FlattenSequence 是一个 lazy adapter -- 惰性适配器。惰性适配器,指带有 lazy
特性,这个特性的作用是按需处理元素,而不是预先处理好所有的工作,Swift 中的 Copy On Write 也是类似的表现。像 FlattenSequence 这样的惰性适配器就起到了算法链具有与原始 for 循环接近的性能表现
上面提到 compactMap
函数里,直接返回的是 Array 类型。那么这时候可以手动加上 lazy 的特性么?
当然也是可以的,在算法链的开头添加 .lazy ,那么在链上任何采用闭包的算法拥有 lazy
特性:
而如果需要最终的结果也是一个 Array 类型,只需要将算法链放在 Array 初始化方法里:
在多数情况下,FlattenSequence 的表现和 Array 一致,视频中原话形容是一个 thin wrapper,占用内存较小而可以比较随意的去生成,而且只要将算法链放进数组的初始化方法 Array()
里就能得到具体类型的数组。在序列只做一次迭代时,利用 lazy
可以节省一些不需要工作。但是需要多次迭代序列的时候就不要适合。此时就可以像 lazy
修饰的存储属性一样,懒加载之后作为属性保存结果。
需要注意的是:将 Array 类型转化成惰性适配器是是不可以的。
开源包里新增的三种数据结构:
这三种也是常见的数据结构类型,而且也是标准集合类型的变体。开源地址:Swift Collection[5]
"double-ended queue" 双端队列,苹果工程师在项目中缩写为了 Deque。双端队列相比较于一般队列的先进先出单个方向的操作,提供了对称性的操作。而在 LeetCode 上就有一道算法题 设计循环双端队列[6] 。
双端队列 Deque 在使用上和 Array 比较接近。在一些方法的底层实现上就大有不同,例如在数组和双端队列中插入数据或翻转数据上,性能有很大的差距。
下面的图片可以看出,在插入新元素的时候,ABC 的位置其实是从后插入的,而改变的是元素对应的索引。在删除中间元素的时候,选择移动前的元素而不是后面的元素,随机删除元素的平均速度提高了一倍。
一般的 Set 通过 hash 函数将元素直接存储在哈希表里,这样能保证元素的唯一性,在查找元素上也有很好的性能,但是元素之间的顺序却是不确定的。而在某些特别的情况下,需要对 Set 中的元素设置一定的顺序。
Swift 实现的 OrderedSet,具体的元素放到了数组里,而原来的哈希表用来存储元素在数组中的索引。索引的范围受哈希表的大小限制,所以通过将整数值换成二进制的方法来压缩表。
Array,Set,OrderedSet 三者在查找,添加,随机删除上的性能比较:
常规的字典使用两个单独的哈希表来存储键值对,而有序字典则是使用单个哈希表和两个数组。
Swift 实现有序字典使用类似数组的整数索引,但是这样会引入一个问题。当索引和 key 值冲突的时候,比如 dict[0]
应该取 key
等于 0 的 value,还是取索引为 0 的 key-value 键值对?Swift 开发工程师认为基于 key 取值是字典的常用操作,所以有序字典里没有提供直接使用索引的操作,而且有序字典也只符合了序列的协议。而符合集合协议的下标操作,通过了 elements 来实现
个人认为,对于算法和数据结构需要做到知其然知其所以然。不同的数据结构有不同的优缺点,Swift 推出更多的类型也是帮助我们能够有更好更多的选择范围。因为是面向协议的实现方式,即使是新增的算法也能在原先数据结构上使用。算法链的使用,包括他的 lazy
特性,也是为了写出更 Swift 化 -- 简洁易懂的代码。
[1]Session 10256: https://developer.apple.com/videos/play/wwdc2021/10256/
[2]SwiftGG - 闭包: https://swiftgg.gitbook.io/swift/swift-jiao-cheng/07_closures#shorthand-argument-names
[3]“懒”点儿好: https://swift.gg/2016/03/25/being-lazy/
[4]Swift Algorithms: https://github.com/apple/swift-algorithms
[5]Swift Collection: https://github.com/apple/swift-collections
[6]设计循环双端队列: https://leetcode-cn.com/problems/design-circular-deque/
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/WpvuuUXQPwBHZpk8OmuPDg
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。