Swift 初学者 ( 12/12 ) 集合

简介

这是一个Swift语言教程,基于最新的iOS 9,Xcode 7.3和Swift 2.2,会为你介绍Swift编程非常基础的内容。从电脑如何工作的全程基本原理到语言结构,你会足够了解这门语言,来处理数据和管理代码的行为。

快速链接


集合

集合(set)是没有顺序的相同类型唯一值的集合。当你想确保一个项目不会在集合里出现多次的时候,它会变得非常有用,并且项目的顺序并不重要。

例如,你想追踪游戏里还有哪些选手是活跃的,就可以用集合。

你对于这里选手的顺序并不感兴趣;你想让集合做的事是存储人并且并不允许他们在集合里出现两次。然后只需要问集合,“Alice 还在游戏里吗?”然后预期得到一个布尔型的 true / false。

如上图所示,没有索引或键可以用来取回值。你会在这篇文章里读到,你仍然可以遍历集合以及查询特定的值在不在集合里。

创建集合

你可以显示声明集合,通过写 Set 紧接着尖括号里加上类型:

let setOne: Set<Int>

Swift 也能从初始化的类型里推断集合的类型:

let setTwo = Set<Int>()

打印 setTwo,你会发现有趣的东西:

print(setTwo)
// > []

它显示了空的集合字面值和空数组的相同。

集合字面值

数组和集合不只是空的字面值相同。事实上,集合没有自己的字面值,用数组字面值来创建带有初始值的集合。看这个例子:

let someArray = [1, 2, 3, 1]

这是一个数组。那怎么用数组字面值创建集合呢?像这样:

let someSet: Set<Int> = [1, 2, 3, 1]

你需要显示声明变量为一个 Set。但是,感谢 Swift 的类型推断,你可以忽略集合包含的值类型:

let anotherSet: Set = [1, 2, 3, 1]

很明显,这是整数集合,所以不需要定义集合的类型。

要用行动看一下集合最重要的特色,让我们打印一下你刚刚创建的集合:

print(someSet)
// > [2, 3, 1]

首先,可以看到没有特定的顺序。其次,尽管你创建的集合带有两个实例值为 1,但这个值只出现了一次——记住,集合的值必须是唯一的。

访问元素

集合里的元素没有索引或键,所以你怎么知道集合到底有没有元素呢,以及怎么访问它拥有的任意元素?就像数组和字典,集合支持 count 和 isEmpty properties。

print(someSet.isEmpty)
// > false
print(someSet.count)
// > 3

可以使用 contains(_:) 来检查特定元素是否存在:

print(someSet.contains(1))
// > true
print(someSet.contains(4))
// > false

你也可以使用 first 和 last properties,返回集合里的一个元素。但是,因为集合没有顺序,你无法确切知道会获得哪个项目。尽管对于尺寸为 0 或 1 的集合,这会是一个获取单一集合元素的快捷方式。

print(someSet.first)
// > Optional(2)

就像预料的,frist 返回了可选值。它必须这样做因为集合可能是空的,在这种情况下 property 会返回 nil。

添加和移除元素

回到纸牌游戏。你想为明天规划一个游戏,希望选择一个对所有人对方便的时间。从建议你自己的适宜时间开始:

var myTimes: Set = ["8am", "9am", "10am"]

你把这个集合声明为变量,因为偏好可能会改变。例如,假设你决定上午 11 点也是开始游戏的耗时间,那就给集合添加另一个元素:

myTimes.insert("11am")
print(myTimes)
// > ["9am", "8am", "11am", "10am"]

insert(_:) 添加了元素到集合;如果元素已经存在,方法什么都不会做。

你意识到上午 8 点太早了。你可以像这样从集合里移除元素:

let removedElement = myTimes.remove("8am")
print(removedElement)
// > Optional("8am")

remove(_:) 返回被移除的元素,如果它在集合里的话,否则就是 nil。

迷你练习

写一个函数移除整数数组里的所有重复。数组?你想问这篇不是关于集合的吗?

小提示:数组有一个用 Set 类型的初始化,集合有一个用 Array 类型的初始化。

遍历集合

当你想遍历集合的元素的时候用 for-in 循环:

for element in myTimes {
    print(element)
}
// > 9am
// > 11am
// > 10am

可以预料,结果没有预先设置的顺序。然而,这和你在其它集合类型里看到的 for-in 语法相似。

集合操作

集合最强大的特色之一就是他们支持集合操作(set operations),允许你把两个集合组成一个,创建只有两个或更多集合的共同值的集合。让我们用你的偏好时间集合来检测这些操作,以及另一组时间。

提醒一下,你提议了游戏时间为上午 9 点,10 点或 11 点。Adam 给你发送了他的偏好时间:

let adamTimes: Set = ["9am", "11am", "1pm"]

让我们依次看看集合操作的四个类型。

Union

union(_:) 创建新集合,带有两个集合所有的值:

let unionSet = myTimes.union(adamTimes)
print(unionSet)
// > ["9am", "11am", "10am", "1pm"]

主要要注意尽管你和 Adam 都选择了上午 9 点 和 上午 11 点为见面好时间,这些值在新集合只出现了一次。

这里,你留下了你和 Adam 提议的每个时间。

Intersect

intersect(_:) 创建新集合,只带有两个集合的共同值。你可以用它创建基于你和 Adam 同意的时间集合。

let intersectSet = myTimes.intersect(adamTimes)
print(intersectSet)
// > ["9am", "11am"]

这里,结果集合里的值就是在 myTimes 和 adamTimes 集合里同时出现的那些。

Subtract

subtract(_:) 创建新集合,移除在第二个集合里出现的值。

let subtractSet = myTimes.subtract(adamTimes)
print(subtractSet)
// > ["10am"]

从 myTimes 里的所有时间开始。然后 subtract(:_) 移除了 adamTimes 里出现的所有时间,留下只有你提议、Adam 没有提议的时间。

这个例子里,上午 10 点是唯一的你提议但没有被 Adam 也提议的时间。

Exclusive Or

exclusiveOr(_:) 创建新集合,带有只在一个集合出现的值,不包括同时具有的。

let exclusiveOrSet = myTimes.exclusiveOr(adamTimes)
print(exclusiveOrSet)
// > ["10am", "1pm"]

这些是你提议但 Adam 没有提议的开始时间,以及 Adam 提议而你没有的开始时间。

迷你练习

快速回答:你会用哪个集合操作来找到见面的合适时间?

集合操作的运行时间

集合和字典有非常相似的实现,他们也需要元素可以被哈希。所有操作的运行时间都和字典的那些相同。

关键点

  • 集合(Sets)是相同类型的唯一值的无序集合。
  • 集合在你需要知道一些东西是不是被包含在集合里的时候最有用处。
  • 可以从数组初始化集合,反之亦然。
  • 集合操作(Set operations)很强力,允许你处理潜在的大量数据来组合和过滤元素。

接下来去哪儿?

既然你现在已经学习了 Swift 里的三种集合类型,你应该很了解他们能做什么以及何时该使用它们。你在继续读教程的时候会看到出现。

现在你知道怎么把数组组合进数组、字典和集合里了,本教程的下一个部分涉及了命名类型(named types)。他们允许你同时组合数据和代码到一起,放到自定义的类型里,作为更大和更好的东西的建筑块!

移步之前,看看下面的挑战来测试你的集合知识。

挑战

挑战 A:你就是编译器

下列哪个为有效语句?

1. let set1: Set<Int> = [1]
2. let set2 = [1]
3. let set3 = Set<Int>()

对于接下来的三条语句,使用这个集合:

let set4: Set = [1, 2, 3]

4. set4[1]
5. set4.insert(1)
6. set4.contains(1)

对于接下来的两条语句,使用这个集合:

var set5: Set = [1, 2, 3]

7. set5.insert("1")
8. set5.remove(1)

挑战 B:检测集合包含的项目

假设你有 10,000 个人的邮箱地址集合:let emails: Set<String>。写一个函数,如果给定的邮箱地址在集合里就返回 true,否则 false。不允许用 contains(_:) 或遍历集合。

挑战 C:追踪到场人数

你是 Swift 大学里的教授,在教一个为期三天的课程。每天,你追踪到场人数,通过到场的每个学生的名字到新的集合里。

例如:

let day1: Set = ["Anna", "Benny", "Charlie"]
let day2: Set = ["Anna", "Benny", "Danny"]
let day3: Set = ["Anna", "Danny", "Eric"]
  1. 写一个函数,返回三天都到了的学生的集合。
  2. 写一个函数判断谁在课程的第一天之后退出了。

这两个函数的结构为:

func funcName(day1: Set<String>, day2: Set<String>, day3: Set<String>) ->Set<String>

挑战和迷你练习源代码

https://yunpan.cn/cMQMgQ3itt7fy (提取码:6680)


介绍

欢迎来到Swift世界!Swift是一门苹果在2014年夏天发布的编程语言。从那之后,Swift发布了一个主要的版本跳跃,成为了开始在苹果平台:iOS,OS X,watchOS和tvOS开发的最简单的方式。

谁适合这篇教程

这篇教程适合懂一点编程、并且希望学习Swift的人。也许你已经为网站写过一些JavaScript代码,或者用Python写过一些简短的程序。这篇教程就是为你准备的!你会学习到编程的基本概念,同时也会成为Swift语言小能手。

如果你是赤裸裸的编程新手,这篇教程也是为你准备的!教程里贯穿有简短的锻炼和挑战来给你一些编程练习,同时测试你的知识。

需要准备什么

要看这篇教程,你需要准备如下的东西:

  • 一台运行OS X El Captian(10.11)的Mac,带有最新发布的更新并且安装了安全补丁。这样你才能够安装需要的开发工具:最新版本的Xcode。
  • Xcode 7.3 或更新的版本。Xcode是用Swift写代码的主要开发工具。最小也需要Xcode 7.3版本,因为那个版本包含Swift 2.2。你可以免费从Mac App Store下载Xcode的最新版本,这里:http://apple.co/1FLn51R

如果你还没有安装Xcode最新版本,在继续看下面的教程前要确定安装。

如何使用这篇教程

每篇教程都会介绍触手可及的话题理论,伴随大量Swift代码来示范在学习的实际的应用程序。

教程里的所有代码都是平台中立的;这意味着不是为iOS、OS X或任何其它平台而特定。代码在playgrounds里运行,你在本篇中已经学习了。

在剩下的教程里,你可以把代码在自己的playground里输入进去。这样你就可以和代码“玩耍”(play around),做一些改变立即就能看见代码运行的结果。

剩下的教程里会贯穿实际小练习,都是简短的练习,关于触手可及的主题。每篇的末尾也有挑战,会有编程问题也会有长一点的代码练习来测试你的知识。做完就能掌握大部分的Swift基础知识。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容