什么是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/