如何在swift中稳定排序数组?

dem*_*lus 10 arrays sorting swift

我一直在使用sort()函数,但它混合了相对顺序.

这就是我的代码看起来的样子.

recipes.sort { $0.skill.value <= $1.skill.value }
Run Code Online (Sandbox Code Playgroud)

Swift API说:

排序算法不稳定.非稳定排序可能会更改比较相等的元素的相对顺序.

如何更改此值以使相对顺序与以前保持一致?

lea*_*vez 18

下面的实现就像sorted标准库中的方法一样,没有额外的限制.

extension RandomAccessCollection {

    /// return a sorted collection
    /// this use a stable sort algorithm
    ///
    /// - Parameter areInIncreasingOrder: return nil when two element are equal
    /// - Returns: the sorted collection
    public func stableSorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element] {

        let sorted = try enumerated().sorted { (one, another) -> Bool in
            if try areInIncreasingOrder(one.element, another.element) {
                return true
            } else {
                return one.offset < another.offset
            }
        }
        return sorted.map { $0.element }
    }
}
Run Code Online (Sandbox Code Playgroud)

稳定的排序需要保留原始订单.所以我们给每个元素一个权重除了它的值,索引,然后原始的排序方法将起作用,因为永远不会有2个相等的元素.


Tom*_*Tom 8

我很欣赏leavez答案的优雅.我把它改编成具有相同的签名Sequence.sorted(by:):

extension Sequence {
  func stableSorted(
    by areInIncreasingOrder: (Element, Element) throws -> Bool)
    rethrows -> [Element]
  {
    return try enumerated()
      .sorted { a, b -> Bool in
        try areInIncreasingOrder(a.element, b.element) ||
          (a.offset < b.offset && !areInIncreasingOrder(b.element, a.element))
      }
      .map { $0.element }
  }
}
Run Code Online (Sandbox Code Playgroud)


Esq*_*uth 7

        let sortedArray = (recipes as NSArray).sortedArray(options: .stable, usingComparator: { (lhs, rhs) -> ComparisonResult in
            let lhs = (lhs as! Recipe)
            let rhs = (rhs as! Recipe)
            if lhs.skill.value == rhs.skill.value {
                return ComparisonResult.orderedSame
            } else if lhs.skill.value < rhs.skill.value {
                return ComparisonResult.orderedAscending
            } else {
                return ComparisonResult.orderedDescending
            }
        })
Run Code Online (Sandbox Code Playgroud)

从这里开始:https://medium.com/@cocotutch/a-swift-sorting-problem-e0ebfc4e46d4

  • 我们必须为此恢复Objective-C真的太糟糕了.为什么他们会选择不稳定的排序作为默认排序?他们真的不能预见到这样的问题吗?叫我疯了,但我会选择稳定性超过性能,至少作为默认值,更不用说唯一的选择了. (4认同)