Swift算法新的序列和集合算法的开源包

256 阅读4分钟

我很高兴地宣布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"]] 

你可以在附带的指南中阅读更多关于chunkedAlgorithms 包中的任何其他组件。

与 Swift 标准库的关系

我们希望标准库能包括一套丰富、实用的通用算法。我们认为Algorithms 包可以帮助实现这一目标,因为它是一个低摩擦的场所,可以建立新的相关算法系列--让我们有机会反复探索问题空间,了解不同算法之间的联系和互动,然后再将它们毕业到标准库中。

像 Swift Algorithms(和Swift Numerics)这样的软件包通过提供以下手段来补充 Swift 进化过程:

  • 在开发过程的早期让社区参与进来
  • 将贡献引向活跃的重点领域
  • 根据现实世界的使用情况征集反馈意见
  • 连贯地解决大量的功能缺失问题。

Algorithms 包在一定程度上是对漫长的SE-0270审查和后续进化过程讨论的回应。对于 SE-0270,我们面临着一个矛盾,即提供一个足够小的提案以有效利用 Swift 讨论区,但又足够大的提案以激励和确保添加内容的一致性。展望未来,我们计划尝试将相关的算法家族分割成多个更小的Evolution提案,利用Algorithms 包的存在来提供额外的背景。

然而,仅仅因为一个新增内容可能是列入Algorithms 包的好候选者,它就不需要在那里开始它的生命。这并不是Swift Evolution 流程的改变。得到良好支持的提案将一如既往地得到考虑。

贡献标准

该包的近期重点是在SequenceCollection 系列协议上孵化一套实用的算法,以便最终纳入 Swift 标准库--你可以在 Pythonitertools模块或 C++算法库中找到这种功能。

有很多有趣和有用的抽象并符合这个标准,比如说:

  • 货币类型(例如:Result )和数据结构(例如:OrderedDictionary )。
  • 一次性的便利(例如:Dictionary.subscript(key:default:) ),不能在Sequence ,或Collection
  • 经典算法(如quicksort、merge sort、heapsort、insertion sort等)与更实用的替代方法
  • 非线性数据结构的算法

对于任何添加到Algorithms 包中的内容,都应该努力收集使用案例,并检查该主题在其他语言和其他平台上的探索方式。为了评估它的适用性,我们应该问:

  • 它是否有助于可读性?
  • 它是一种常见的操作吗?
  • 它与现有的抽象一致吗?
  • 它是否有助于避免正确性陷阱?
  • 它是否有助于避免性能陷阱?

...或者反过来说:

  • 它是否是琐碎的可组合的?(例如:!isEmpty)
  • 它可能会鼓励滥用吗?