我很高兴地宣布Swift算法,一个新的序列和集合算法的开源包,以及它们的相关类型。
算法是强大的思想工具,因为它们封装了难以阅读和容易出错的原始循环。Algorithms 包包括一系列强大的通用算法,这些算法经常出现在其他流行的编程语言中。我们希望这个新包能够帮助人们接受算法,提高他们代码的正确性和性能。
简要浏览
通过Algorithms 包中最初的一组序列和集合操作,你可以在一个集合的元素上循环,找到组合和排列,创建一个随机样本,等等。
其中包括一对chunked 方法,每个方法都能将一个集合分成连续的子序列。其中一个版本测试相邻的元素,以找到各块之间的断裂点--你可以用它来快速将一个数组分离成升序运行:
let numbers = [10, 20, 30, 10, 40, 40, 10, 20]
let chunks = numbers.chunked(by: { $0 <= $1 })
// [[10, 20, 30], [10, 40, 40], [10, 20]]
另一个版本则是寻找每个连续值的转换变化。你可以用它来把一个名字列表按第一个字符分成若干组:
let names = ["Cassie", "Chloe", "Jasmine", "Jordan", "Taylor"]
let chunks = names.chunked(on: \.first)
// [["Cassie", "Chloe"], ["Jasmine", "Jordan"], ["Taylor"]]
你可以在附带的指南中阅读更多关于chunked 或Algorithms 包中的任何其他组件。
与 Swift 标准库的关系
我们希望标准库能包括一套丰富、实用的通用算法。我们认为Algorithms 包可以帮助实现这一目标,因为它是一个低摩擦的场所,可以建立新的相关算法系列--让我们有机会反复探索问题空间,了解不同算法之间的联系和互动,然后再将它们毕业到标准库中。
像 Swift Algorithms(和Swift Numerics)这样的软件包通过提供以下手段来补充 Swift 进化过程:
- 在开发过程的早期让社区参与进来
- 将贡献引向活跃的重点领域
- 根据现实世界的使用情况征集反馈意见
- 连贯地解决大量的功能缺失问题。
Algorithms 包在一定程度上是对漫长的SE-0270审查和后续进化过程讨论的回应。对于 SE-0270,我们面临着一个矛盾,即提供一个足够小的提案以有效利用 Swift 讨论区,但又足够大的提案以激励和确保添加内容的一致性。展望未来,我们计划尝试将相关的算法家族分割成多个更小的Evolution提案,利用Algorithms 包的存在来提供额外的背景。
然而,仅仅因为一个新增内容可能是列入Algorithms 包的好候选者,它就不需要在那里开始它的生命。这并不是对Swift Evolution 流程的改变。得到良好支持的提案将一如既往地得到考虑。
贡献标准
该包的近期重点是在Sequence 和Collection 系列协议上孵化一套实用的算法,以便最终纳入 Swift 标准库--你可以在 Pythonitertools模块或 C++算法库中找到这种功能。
有很多有趣和有用的抽象并不符合这个标准,比如说:
- 货币类型(例如:
Result)和数据结构(例如:OrderedDictionary)。 - 一次性的便利(例如:
Dictionary.subscript(key:default:)),不能在Sequence,或Collection - 经典算法(如quicksort、merge sort、heapsort、insertion sort等)与更实用的替代方法
- 非线性数据结构的算法
对于任何添加到Algorithms 包中的内容,都应该努力收集使用案例,并检查该主题在其他语言和其他平台上的探索方式。为了评估它的适用性,我们应该问:
- 它是否有助于可读性?
- 它是一种常见的操作吗?
- 它与现有的抽象一致吗?
- 它是否有助于避免正确性陷阱?
- 它是否有助于避免性能陷阱?
...或者反过来说:
- 它是否是琐碎的可组合的?(例如:
!isEmpty) - 它可能会鼓励滥用吗?