「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
Swift Algorithms 是 Swift 官方开源的一个框架,它主要提供一些作用于序列和集合的一些算法,以此来提高开发者的开发效率。
本文主要讲解以下几个内容:
- 如何安装
- 组合与排列
- collection 的组合
- 子序列的相关操作
- 部分排序 废话不多说,下面让我们开始吧!
安装 Swift-Algorithms
点击 Xcode 的 File
,选中菜单中的 Add Packages
,在搜索框输入 Swift algorithms
,点击底部的 add package
按钮即可安装。
安装完成之后,在需要使用的地方 import Algorithms
。如果在导入之后报错:No such module
,请按照下面的操作进行修复:
Project Settings -> General -> My Target -> Frameworks, Libraries, and Embedded Content
点击下方 + 号,添加 Algorithms
组合与排列
获取集合元素的全排列 - combinations
假设,我们有一组数据,用来表示所有人的名字:
let names = ["伍六七", "鸡大保", "梅花十一", "梅花十三"]
我们接到一个需求,需要得到数组中的所有元素可以组出多少组的 CP,代码如下:
for cp in names.combinations(ofCount: 2) {
print(cp)
}
// 所有的 CP 组合
//["伍六七", "鸡大保"]
//["伍六七", "梅花十一"]
//["伍六七", "梅花十三"]
//["鸡大保", "梅花十一"]
//["鸡大保", "梅花十三"]
//["梅花十一", "梅花十三"]
需要注意的点:
- 该函数的返回结果是有序的,按照元素的顺序返回排列。
- 该函数不会进行去重操作。
let numbers2 = [20, 10, 10]
for combo in numbers2.combinations(ofCount: 2) {
print(combo)
}
// 此处可以看到,[20, 10]出现两次。
// [20, 10]
// [20, 10]
// [10, 10]
更灵活的用法
combinations 不仅可以传递一个值,还可以传递一个范围。比如,我们可以统计 2 个元素和 3 个元素的全排列:
for result in names.combinations(ofCount: 2...3) {
print(result)
}
// ["伍六七", "鸡大保"]
// ["伍六七", "梅花十一"]
// ["伍六七", "梅花十三"]
// ["鸡大保", "梅花十一"]
// ["鸡大保", "梅花十三"]
// ["梅花十一", "梅花十三"]
// ["伍六七", "鸡大保", "梅花十一"]
// ["伍六七", "鸡大保", "梅花十三"]
// ["伍六七", "梅花十一", "梅花十三"]
// ["鸡大保", "梅花十一", "梅花十三"]
collection 的组合
合并两个集合 - chain
如果不适用 Algorithm,我们会写下面的代码去访问两个集合中的元素:
let names1 = ["伍六七", "鸡大保", "梅花十一", "梅花十三"]
let names2 = ["青凤", "江主任"]
for name in names1 + names2 {
print(name)
}
而有了 Algorithm 之后,我们可以用 chain 来优化下面的代码:
for name in chain(names1, names2) {
print(name)
}
看到上面的代码,你可能会有一个疑惑:看起来就是把 + 换成了 chain 啊?
使用 chain 有下面两个好处:
- 它只是存储集合的引用,不会去执行任何的 allocations 操作,而 + 实际上会创建一个临时变量。
- chain 可以应用于任意的 sequence 类型,比如 range 和 Array:
let reservedSeats = 0...50
let unavailableSeats = [61, 68, 75, 76, 77, 92]
let disallowed = chain(reservedSeats, unavailableSeats)
let requestedSeat = 39
print(disallowed.contains(requestedSeat))
重复元素
通过 cycled
函数,可以进行集合元素的重复:
for name in names2.cycled(times: 2) {
print(name)
}
//青凤
//江主任
//青凤
//江主任
cycled
函数的本质等同于 repeatElement(_:count:)
+ joined()
。
product
product
主要用于一个集合的每个元素去遍历访问另一个集合的元素。
比如,当前有两个集合:names 和 actions:
let actions = ["吃早餐", "吃午餐", "吃晚餐"]
let names = ["青凤", "江主任"]
我们每个人都需要每日吃三餐。所以,需要 names 中的每个元素去遍历 actions 的 action:
for (person, action) in product(names, actions) {
print(person, action)
}
//青凤 吃早餐
//青凤 吃午餐
//青凤 吃晚餐
//江主任 吃早餐
//江主任 吃午餐
//江主任 吃晚餐
子序列的相关操作
同时获取最小值和最大值
使用 minAndMax
,等同于 min + max:
let numbers = [7, 1, 6, 2, 8, 3, 9]
if let (smallest, largest) = numbers.minAndMax() {
print(smallest, largest) // 1 9
}
去重
使用 uniqued()
进行集合去重:
let names = ["梅花十一", "青凤", "伍六七", "江主任", "伍六七", "鸡大保", "梅花十一"]
let unique = names.uniqued()
print(Array(unique)) // ["梅花十一", "青凤", "伍六七", "江主任", "鸡大保"
部分排序
使用 min(count:) 或者 max(count:) 来返回几个最大值或者最小值:
let numbers = [2, 4, 9, 5, 8]
print(numbers.min(count: 3)) // [2, 4, 5]
最后
本文只是对 Algorithm 框架的一个基本的介绍,其中还包括很多好玩的函数没有包含在本文中。十分推荐大家去看一下官方文档,去探索更多非常酷的功能。