Swift 入门学习:集合(Collection)类型趣谈-下

在这里插入图片描述

概览

集合的概念在任何编程语言中都占有重要的位置,正所谓:“古来聚散地,宿昔长荆棘;游人聚散中,一片湖光里”。把那一片片、一瓣瓣、一粒粒“可耐”的小精灵全部收拢、吸纳的井然有序、条条有理,怎能不让我们满心欢喜呢?

在这里插入图片描述

在 Swift 入门学习:集合(Collection)类型趣谈-上 这篇博文中,我们已初步学习了集合的相关知识。而在下篇中,我们将继续集合的探索之旅。

在本篇博文中,您将学到如下内容:

  • 概览
  • 4. Set
  • 5. “无限大”的范围类型(Range)
  • 6. 标准库集合的扩展
  • 总结

Swift 中集合的概念简约而不简单,所以让我们闲言少叙,马上开始吧。

Let’s collect it now!!!😉


4. Set

Set 也是一种集合类型,它同样要求其内部元素都遵守 Hashable 协议:

在这里插入图片描述

字典类似, Set 也是无序的。而且每个 Hashable 值相同的元素只能在 Set 中出现一次:

在这里插入图片描述

与其它集合类似,我们也可以方便的遍历它的元素:

let set = Set<Int>([1,2,2,3,3,4,4,5,5])for i in set {print(i)
}let ary = set.map { $0 * $0}

与其它集合所不同的是,我们可以对其进行数学上的基本集合操作(Fundamental Set Operations)。

在这里插入图片描述

比如:计算两个 Set 间的并集、交集、对称差等等:

let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]

我们还可以测试集合间的归属性和相等性(Set Membership and Equality):

在这里插入图片描述

比如在下面的代码中,我们就分别检查了 houseAnimals 是否是 farmAnimals 的子集、farmAnimals 是否是 houseAnimals 的超集、以及 farmAnimals 是否和 cityAnimals 完全不搭噶:

let houseAnimals: Set = ["🐶", "🐱"]
let farmAnimals: Set = ["🐮", "🐔", "🐑", "🐶", "🐱"]
let cityAnimals: Set = ["🐦", "🐭"]houseAnimals.isSubset(of: farmAnimals)
// true
farmAnimals.isSuperset(of: houseAnimals)
// true
farmAnimals.isDisjoint(with: cityAnimals)
// true

从上面的讨论可知,除了一般意义上的集合,Set 还可以被当做数学概念上的集合来使用。

可能有的小伙伴们并不知道,早在 Objective-c 的“远古时代”就存在一种计数 Set 类型:NSCountedSet,它是 Set 的一种变体:

在这里插入图片描述

它也被用来表示一个 Set,但其中相同的元素可以重复出现。注意它是作为一个类(而不是结构)实现的:

在这里插入图片描述

5. “无限大”的范围类型(Range)

小伙伴们可能会好奇:Swift 中的集合到底能不能包含无穷多个元素?

包含无限元素的集合对于一些动态语言来说简直不要太容易,比如 ruby 语言:

在这里插入图片描述

那么,对于 Swift 这种貌似偏静态的语言也能办得到吗?答案是肯定的!

在 Swift 语言中,有一种范围(Range)类型专门用来表示一段范围内元素的集合。注意这是一种“半包(half-open)”类型,因为 Range 中的元素并不包括它的上界(upper bound)。

在这里插入图片描述

大家可能会猜到,为了增加灵活性还有一种“全包”的 Range 类型:ClosedRange。
在这里插入图片描述

创建 Range 实例更是小菜一碟,我们可以一如既往的用语法糖或是构造器来实现:

// 从 1 开始,不包括 10;下同
let half_range = 1..<10
let half_range_1 = Range(uncheckedBounds: (1,10))
// 从 1 开始,包括 10;下同
let range = 1...10
let range_1 = ClosedRange(uncheckedBounds: (1,10))

同样的,遍历范围的操作也好似“蜻蜓点水”:

for i in half_range {print(i)
}half_range.forEach { print($0)}

因为 Range 也是一种集合,所以我们可以把它轻松转换为数组:

let half_range = 1..<10
let ary = Array(half_range)

之前在介绍数组时提到过惰性序列,Range 就可以被看做一种 LazySequence。这意味着,我们可以用几乎忽略不计的代价就创建出非常“巨大”的 Range:

// 瞬间即可创建包含海量元素的 Range
let half_range = 1..<10000000000
for i in half_range.prefix(10) {print(i)
}

因为 Range 是一种惰性序列,所以它的元素只有在实际使用时才会被求值,这使得它的创建开销非常小。相反,如果我们要创建一个包含 100 亿个元素的 Array,即使只会用到前 10 个,内存也会“实打实”的被 100 亿个元素所占用,真是让人欲哭无泪!

由于 Range 足够“懒惰”,它可以表示无穷个元素。比如,在如下代码中我们用 inf_range 来表示所有自然数:

// 包含所有自然数的范围
let inf_range = 1...
for i in inf_range {if i > 10 { break }print(i)
}// 千万别这么做!!!
let inf_ary = Array(inf_range)

对于“无限大”的范围,千万不要试图将其转换为 Array,因为除了无限挂起你啥也得不到。


有的小伙伴对于上面自然数的定义会有不同看法,他们会认为 0 也是自然数。对于这个有趣问题,我写过一篇同样有趣的博文,感兴趣的小伙伴们可以猛戳以下链接观赏:

  • 有趣的小实验:五种语言搞定“超超超难”剑桥面试数学题

在这里插入图片描述


由于 Range 的惰性特质加持,当仅需处理海量数据中的一小部分时,我们可以优先考虑它。当然,普通的数组也是可以转换为惰性序列的:

let MAX = 10000
// 创建一个包含 1w 个元素的数组,并初始化
var ary = [Int](repeating: 0, count: MAX)for i in 0..<MAX {ary[i] = i * i
}let lazy_ary = ary.lazy
for i in lazy_ary {guard i < 100 else { break }print(i)
}

6. 标准库集合的扩展

在学完上面那么多集合类型之后,如果小伙伴们还是觉得找不到“趁手的兵器”,那么除了自己打造全新的“雷神之锤”以外,我们还可以使用 Apple 官方的 Swift Collections 框架:

在这里插入图片描述

  • Swift Collections

Swift Collections 包括了一些 Swift 标准库中未实现的超实用集合类型,比如:BitSet、Deque、Heap 等等,完整的集合类型列表在此:

在这里插入图片描述
在这里插入图片描述

可以看到,Swift Collections 框架中包括了 SortedSet 和 SortedDictionary 两种集合类型。它们分别对应于标准库中的 Set 和 Dictionary 类型,但却是有序的。

我们可以通过 SPM 的方式将 Swift Collections 框架方便的导入到自己的项目中,然后大家就可以发挥天马行空的想象力来驾驭里面各个绝妙的集合利器啦!棒棒哒!

总结

在本篇博文中,我们接上篇继续介绍了 Swift 语言中集合类型 Set,并讨论了如何用 Range 类型来表示无穷多元素的集合;我们还介绍了苹果官方 Swift Collections 框架中更多的集合类型,超赞的哦。

感谢观赏,再会!😎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/272874.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

恋活2 仿原神人物卡系列2全合集打包

内含&#xff1a;炽沙话事人 芭别尔迪希雅镀金女团 -沙中净水镀金女团 -叶轮舞者珐露珊坎蒂丝柯莱可莉丽莎-叶隐芳名神里绫华-花时来信瑶瑶。 下载地址&#xff1a; https://www.changyouzuhao.cn/13661.html

C++ Standard Library简介

目录 ​编辑 引言&#xff1a; Boost C Libraries&#xff1a;截至本文编写时间最新版本 1.84.0 STL源码分析&#xff1a; C STL源码分析&#xff08;一&#xff09;&#xff1a;STL体系结构和一些基础知识 libc&#xff1a; 概述 libc 入门 现状 平台和编译…

(黑马出品_03)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

&#xff08;黑马出品_03&#xff09;SpringCloudRabbitMQDockerRedis搜索分布式 微服务技术Docker 今日目标1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2…

Java共享问题 、synchronized 线程安全分析、Monitor、wait/notify

文章目录 1.共享带来的问题1.1 临界区 Critical Section1.2 竞态条件 Race Condition 2. synchronized语法及理解2.1 方法上的 synchronized 3.变量的线程安全分析3.1.成员变量和静态变量是否线程安全&#xff1f;3.2.局部变量是否线程安全&#xff1f;3.2.1 局部变量线程安全分…

ElasticSearch架构介绍及原理解析

Elasticsearch 是一个高度可扩展的开源全文搜索和分析引擎&#xff0c;用于处理大量的数据。它是由 Elasticsearch BV 公司开发&#xff0c;并且是用 Java 语言编写的。Elasticsearch 基于 Lucene 搜索引擎&#xff0c;提供了 RESTful API&#xff0c;允许你通过 JSON 格式的请…

DFS例题(n皇后问题)C++(Acwing)

代码&#xff1a; #include <iostream>using namespace std;const int N 20;int n; char g[N][N]; bool col[N], dg[N], udg[N];void dfs(int u) {if(u n){for(int i 0; i < n; i) puts(g[i]);puts("");return; }for(int i 0; i < n…

数字化审计智慧

简析内部审计数字化转型的方法和路径 内部审计是一种独立的、客观的确认和咨询活动&#xff0c;包括鉴证、识别和分析问题以及提供管理建议和解决方案。狭义的数字化转型是指将企业经营管理和业务操作的各种行为、状态和结果用数字的形式来记录和存储&#xff0c;据此再对数据进…

【xv6操作系统】Lab systems calls

一、实验前须知 阅读 xv6 文档的第 2 章和第 4 章的 4.3 节和 4.4 节以及相关源文件&#xff1a; 系统调用的用户空间代码在 user/user.h 和 user/usys.pl 中。 内核空间代码在 kernel/syscall.h 和 kernel/syscall.c 中。 与进程相关的代码在 kernel/proc.h 和 kernel/proc.c…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:ImageSpan)

Text组件的子组件&#xff0c;用于显示行内图片。 说明&#xff1a; 该组件从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 ImageSpan(value: ResourceStr | PixelMap) 参数&#xff1a; 参数名参数类…

大模型学习过程记录

一、基础知识 自然语言处理&#xff1a;能够让计算理解人类的语言。 检测计算机是否智能化的方法&#xff1a;图灵测试 自然语言处理相关基础点&#xff1a; 基础点1——词表示问题&#xff1a; 1、词表示&#xff1a;把自然语言中最基本的语言单位——词&#xff0c;将它转…

两天学会微服务网关Gateway-Gateway网关限流

锋哥原创的微服务网关Gateway视频教程&#xff1a; Gateway微服务网关视频教程&#xff08;无废话版&#xff09;_哔哩哔哩_bilibiliGateway微服务网关视频教程&#xff08;无废话版&#xff09;共计17条视频&#xff0c;包括&#xff1a;1_Gateway简介、2_Gateway工作原理、3…

python基础——条件判断和循环【if,while,for,range】

&#x1f4dd;前言&#xff1a; 这篇文章主要讲解一下条件判断语句if和循环语句while&#xff0c;for在python中需要注意的地方。 建议已有一定了解&#xff08;对语句的执行逻辑清楚&#xff09;的读者观看&#xff0c;如果对条件判断和循环的执行逻辑不太清楚&#xff0c;也可…

win11家庭版docker和milvus

docker 1、官网下载docker文件Get Started | Docker&#xff0c;选择download for windows下载。 2、双击打开下载好的文件Docker Desktop Installer.exe&#xff0c;add shortcut to desktop选择√代表同意添加快捷键到桌面&#xff0c;如果不勾选就说明不创建快捷键&#x…

阿里云服务器多少钱1个月?2024年最新报价5元一个月

阿里云服务器一个月多少钱&#xff1f;最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年&#xff0c;折合5元一个月&#xff0c;2核4G服务器30元3个月&#xff0c;2核2G3M带宽服务器99元12个月&#xff0c;轻量应用服务器2核4G4M带宽165元12个月&#xff0c;4核16G服务…

跨平台大小端判断与主机节序转网络字节序使用

1.macOS : 默认使用小端 ,高位使用高地址,转换为网络字节序成大端 #include <iostream> #include <arpa/inet.h> int main() {//大小端判断union{short s;char c[sizeof(short)];}un;un.s = 0x0102;printf("低地址:%d,高地址:%d\n",un.c[0],un.c[1]);if …

安卓部分手机使用webview加载链接后白屏(Android低版本会出现的问题)

前言 大爷&#xff1a;小伙我这手机怎么打开你们呢这个是白屏什么都不显示。 大娘&#xff1a;小伙我这也是打开你们呢这功能&#xff0c;就是一个白屏什么也没有&#xff0c;你们呢的应用不会有病毒吧。 小伙&#xff1a;我的手机也正常&#xff1b; 同事&#xff1a;我的也正…

【Flink】Flink 的八种分区策略(源码解读)

Flink 的八种分区策略&#xff08;源码解读&#xff09; 1.继承关系图1.1 接口&#xff1a;ChannelSelector1.2 抽象类&#xff1a;StreamPartitioner1.3 继承关系图 2.分区策略2.1 GlobalPartitioner2.2 ShufflePartitioner2.3 BroadcastPartitioner2.4 RebalancePartitioner2…

全栈的自我修养 ———— css中常用的布局方法flex和grid

在项目里面有两种常用的主要布局:flex和grid布局&#xff08;b站布局&#xff09;&#xff0c;今天分享给大家这两种的常用的简单方法&#xff01; 一、flex布局1、原图2、中心对齐3、主轴末尾或者开始对其4、互相间隔 二、grid布局1、基本效果2、加间隔3、放大某一个元素 一、…

Linux第74步_“设备树”下的LED驱动

使用新字符设备驱动的一般模板&#xff0c;以及设备树&#xff0c;驱动LED。 1、添加“stm32mp1_led”节点 打开虚拟机上“VSCode”&#xff0c;点击“文件”&#xff0c;点击“打开文件夹”&#xff0c;点击“zgq”&#xff0c;点击“linux”&#xff0c;点击“atk-mp1”&am…

基于GAN对抗网进行图像修复

一、简介 使用PyTorch实现的生成对抗网络&#xff08;GAN&#xff09;模型&#xff0c;包括编码器&#xff08;Encoder&#xff09;、解码器&#xff08;Decoder&#xff09;、生成器&#xff08;ResnetGenerator&#xff09;和判别器&#xff08;Discriminator&#xff09;。…