Swift Collections简单使用

什么是Swift Collections?

Swift Collections是一个新(2021年4月5日)的开源程序包,旨在将Swift程序员可用的数据结构的选择范围扩展到标准库中提供的数据结构之外。在其初始版本中,它提供双端队列(Deque),有序集合(OrderedSet)和有序字典(OrderedDictionary)。

什么是双端队列(Deque)?

双端队列(Deque)的工作原理类似于Array:它是一个有序,随机访问,可变的,范围可替换的,具有整数索引的集合。

双端队列(Deque)比数组(Array)更有优势的是它支持支持两端的有效插入和移除。

理解什么是队列?

队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性表。允许插入的一端称为队尾,允许删除的一端称为队头。队列可以提供先进先出的顺序(FIFO)。

导入头文件
import Collections
双端队列的基本使用
var numbers: Deque = ["2", "3", "4"]
//在头部添加元素
numbers.prepend("1")
//在尾部添加元素
numbers.append("6")
//在特定位置插入元素
numbers.insert("5", at: 4)
// `numbers` is now ["1", "2", "3", "4", "5", "6"]
//删除元素
print(numbers.popFirst()!)// 1 移除"1"
print(numbers.popLast()!)// 5 移除"5"
print(numbers)// [2, 3, 4, 5]
//获取元素
print(numbers[0])// 2
//修改元素
numbers[1]="1"
print(numbers)// [2, 1, 4, 5]
//排序
numbers.sort()
print(numbers)// [1, 2, 4, 5]
//移除元素
numbers.remove(at: 0)
numbers.removeFirst(1)
numbers.removeLast()
numbers.removeAll()
移除符合条件的元素
var deque = Deque([1, 2, 3, 4, 5, 6])
deque.removeAll { (element) -> Bool in
    if element % 2 == 0 {
        return true
    }
    return false
}
print(deque)//[1, 3, 5]

什么是有序集合(OrderedSet)?

有序集合(OrderedSet)是一个数组(Array)和一个集合(Set)的混合体。这意味着OrderedSet可以像传统集合(Set)一样有效地检查元素是否在集合内,并且还可以像数组(Array)一样在特定位置检索元素。

导入头文件
import Collections
有序集合的基本使用
var orderedSet = OrderedSet(["case0","case1","case2"])
//var orderedSet : OrderedSet = ["case1", "case2"]
//遍历元素       
orderedSet.forEach { (element) in
      print(element)
 }
//添加元素
orderedSet.append("case3")
orderedSet.append(contentsOf: ["case4","case5","case6"])
 //["case0","case1","case2","case3","case4","case5","case6"]
//获取元素
 orderedSet[0]
 //移除元素
orderedSet.remove(at: 0)
orderedSet.remove("case2")
orderedSet.removeFirst()
orderedSet.removeFirst(1)
orderedSet.removeLast()
orderedSet.removeLast(1)
orderedSet.removeAll()

// 移除符合条件的元素
var intOrderedSet = [1,2,3,4,5,6,7,8]
intOrderedSet.removeAll { (elment) -> Bool in
      if elment % 2 == 0 {
        return true
      }
        return false
}
//[1, 3, 5, 7]
Uion

取两个集合(Set)的并集

let orderedSet = OrderedSet(["1", "2", "4"])
let newOrderedSet = orderedSet.union([
    "2", "3", "1"
])
print(newOrderedSet)//[1, 2, 4, 3]
Intersection

取两个集合(Set)的交集

let orderedSet = OrderedSet([
    "0", "1", "2", "3", "4"
])
let newOrderedSet = orderedSet.intersection([
    "3", "2", "0"
])
print(newOrderedSet)//[0, 2, 3]
删除重复数据

OrderedSet可以在保留原始元素顺序的同时对有序元素进行重复数据删除

let timeSeries = [
    ["id": "0", "value": "0"],
    ["id": "1", "value": "1"],
    ["id": "0", "value": "0"],
    ["id": "2", "value": "2"],
    ["id": "1", "value": "1"]
]
let orderedUniqueSeries = OrderedSet(timeSeries)
print(orderedUniqueSeries)
//["id": "0", "value": "0"],
//["id": "1", "value": "1"],
//["id": "2", "value": "2"]

什么是有序字典(OrderedDictionary)?

当元素的顺序很重要或我们需要能够有效访问集合中各个位置的元素时,字典(OrderedDictionary)是字典(Dictionary)的有效的替代方法。

导入头文件
import Collections
有序字典的基本使用
var orderedDict: OrderedDictionary = [
    "key0": 0,
    "key1": 1
]
//插入键值对
orderedDict["key3"] = 3
orderedDict["key2"] = 2
orderedDict["key4"] = 4
orderedDict["key5"] = 5
print(orderedDict)//[key0: 0, key1: 1, key3: 3, key2: 2, key4: 4, key5: 5]
//获取key对应的value
print(orderedDict["key1"]!) // 1
//此外,OrderedDictionary它具有内部顺序,并且可以使用elements属性来检索顺序中特定位置的值:
let element = orderedDict.elements[0]
print(element.key) // "key0"
print(element.value) // 0
//删除键值对
orderedDict.removeValue(forKey: "key1")
orderedDict.remove(at: 0)
orderedDict.removeFirst()
orderedDict.removeFirst(1)
orderedDict.removeLast()
orderedDict.removeFirst(1)
orderedDict.removeAll()
移除符合条件的元素
var orderedDict: OrderedDictionary = [
    "key0": 0,
    "key1": 1
]
// Filter keys and values
orderedDict.removeAll { (key, value) -> Bool in
    if key == "key0" {
        return true
    }
    return false
}
print(orderedDict)//[key1: 1]
计数器

计数器通常用于确定序列中唯一元素出现的次数。有序计数器允许对唯一元素的出现进行计数,同时还保留了先见顺序:

let sequence = [
    "a", "b", "a", "c", "b", "b", "b", "a"
]

var orderedCounter: OrderedDictionary<String,Int> = [:]

for item in sequence {
    orderedCounter[item, default: 0] += 1
}

print(orderedCounter)//[a: 3, b: 4, c: 1]
print(orderedCounter["b"]!)// 4

let element = orderedCounter.elements[0]
print(element.key)// "a"
print(element.value)// 3
随机访问唯一的有序元素

当使用唯一序列时,按顺序访问唯一序列的元素并使用唯一标识符通常很有用。OrderedDictionary提供可以同时执行以下操作的类型:

let timeSeries = [
    ["id": "t0", "value": "0.1"],
    ["id": "t1", "value": "1.1"],
    ["id": "t2", "value": "2.1"]
]

var series: OrderedDictionary<String, Dictionary<String,String>> = [:]

for datapoint in timeSeries {
    series[datapoint["id"]!] = datapoint
}

print(series)
//[t0: ["value": "0.1", "id": "t0"], t1: ["value": "1.1", "id": "t1"], t2: ["value": "2.1", "id": "t2"]]

print(series["t1"]!)// ["id": "t1", "value": "1.1"]
 
let element = series.elements[2]
print(element.key)// "t2"
print(element.value)// ["id": "t2", "value": "2.1"]

项目通过SwiftPM(Swift Package Manager)引入Swift Collections Package

新建一个Swift项目,Xcode Menu -> File -> Swift Packages -> Add Package Dependency...操作后如下图

在搜索框🔍中输入需要的依赖库的Github地址,本文使用的是Swift Collections的依赖库,Github地址:https://github.com/apple/swift-collections

点击Next进入下一步显示如下图


Up to Next Major: 当前指定的版本号到下一个大版本号之间的最新版本,例如 2.0.0 ~ 3.0.0(不包含 3.0.0)
Up to Next Minor: 当前指定的版本号到下一个次版本号之间的最新版本,例如 2.0.0 ~ 2.1.0(不包含 2.1.0)
Range: 指定的两个版本号之间的最新版本,例如 2.1.0 ~ 2.7.2(不包含 2.7.2)
Exact: 指定使用某一具体的版本号

点击Next进入下一步显示如下图


同时,我们也可以指定要依赖当前 Package git 仓库的某一个分支或者某一次 commit。

最后,勾选当前 Package 要添加到工程中的哪些 Targets,即可。

全选,然后点击Finish



在ViewController中导入就可以使用了


总结

@EyreFree:Swift Collections专注于扩展可用的 Swift 数据结构集。我们都知道目前 Swift 标准库实现了三种最基本的通用数据结构:数组、集合和字典,但很多时候为了更高效地解决问题,开发者们往往需要借助一些其他的数据结构。现在官方已经注意到了这一点,通过提供 Collections 库来让开发者们能够花费尽可能少的精力来编写更快、更可靠的程序,它的初始版本包含了三种最常见的数据结构:双端队列 Deque、有序集合 OrderedSet 和有序字典 OrderedDictionary。

参考文献
[1]Introducing Swift Collections : https://swift.org/blog/swift-collections
[2]Swift Collections Github : https://github.com/apple/swift-collections
[3]在 Xcode 中使用 Swift Package : https://xiaozhuanlan.com/topic/9635421780
[4]Rob Blog : https://www.advancedswift.com/author/rob/

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

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,704评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,872评论 1 6
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,518评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,582评论 2 9