【问题标题】:Comparable extension works but gives bad results可比较的扩展有效,但结果不佳
【发布时间】:2018-05-23 12:29:11
【问题描述】:

我为 Array 编写了 Comparable 扩展:

extension Array:Comparable where Element == Double {
     public static func < (lhs: Array<Element>, rhs: Array<Element>) -> Bool {
         let count = Swift.min(lhs.count, rhs.count)
         for i in 0..<count {
             if lhs[i] < rhs[i]  { return true }
        }
        return false
    }
}

对于元组类:

extension Tuple:Comparable where T == Double {
    static func < (lhs: Tuple<T>, rhs: Tuple<T>) -> Bool {
        print ("compare \(lhs) \( lhs.content < rhs.content ? "<" : ">=") \(rhs)")
        return lhs.content < rhs.content
    }
}

当我打电话时

return Array<This>(newVertices.sorted(by: { $0.position < $1.position}))

列表看起来不错,元组 func &lt; (lhs: Array&lt;Element&gt;, rhs: Array&lt;Element&gt;) 被调用,结果很奇怪:

错误,100 > 55:

compare Tuple<Double> 3-D: [100.0, 0.0, 55.0, ] < Tuple<Double> 3-D: [55.0, 55.0, 300.0, ]

错误,100 > 0:

compare Tuple<Double> 3-D: [100.0, 0.0, 55.0, ] < Tuple<Double> 3-D: [0.0, 55.0, 300.0, ]

嗯,好的... 100 > 55

compare Tuple<Double> 3-D: [100.0, 0.0, 55.0, ] >= Tuple<Double> 3-D: [55.0, 0.0, 55.0, ]

好的,-100

compare Tuple<Double> 3-D: [-100.0, 55.0, 300.0, ] < Tuple<Double> 3-D: [55.0, 55.0, 300.0, ]

好的,-100

compare Tuple<Double> 3-D: [-100.0, 55.0, 300.0, ] < Tuple<Double> 3-D: [0.0, 55.0, 300.0, ]

好的,-100

compare Tuple<Double> 3-D: [-100.0, 55.0, 300.0, ] < Tuple<Double> 3-D: [100.0, 0.0, 55.0, ]

哪里可能出错了?

【问题讨论】:

  • 您的数组比较运算符错误。 [100.0, 0.0, 55.0, ] 应该大于 [55.0, 55.0, 300.0, ]
  • 是的,我发现并编辑了帖子。但我在 Array Extension 中看不到错误。

标签: arrays swift sorting


【解决方案1】:

您的数组比较函数无效,没有提供 “strict weak ordering”:

let a = [2.0, 1.0, 3.0]
let b = [1.0, 2.0, 4.0]

print(a < b) // true
print(b < a) // true

对于字典顺序,您必须尽快返回 false lhs[i] &gt; rhs[i] 用于某些索引,而不是继续循环。 同样,一个数组是另一个数组的前缀的情况也不是 处理。

这将是一个正确的实现:

extension Array: Comparable where Element == Double {
    public static func < (lhs: Array<Element>, rhs: Array<Element>) -> Bool {
        let count = Swift.min(lhs.count, rhs.count)
        for i in 0..<count {
            if lhs[i] < rhs[i]  { return true }
            if lhs[i] > rhs[i]  { return false }
        }
        return lhs.count < rhs.count
    }
}

可以简化和推广到

extension Array: Comparable where Element: Comparable {
    public static func < (lhs: Array<Element>, rhs: Array<Element>) -> Bool {
        for (l, r) in zip(lhs, rhs) {
            if l < r { return true }
            if l > r { return false }
        }
        return lhs.count < rhs.count
    }
}

例子:

print( [2.0, 1.0, 3.0] < [1.0, 2.0, 4.0]) // false
print( [1.0, 2.0, 4.0] < [2.0, 1.0, 3.0]) // true
print( [1.0] < [1.0, 2.0]) // true
print( [1.0, 2.0] < [1.0, 2.0]) // false
print( [1.0, 2.0] < [1.0]) // false

【讨论】:

  • 不错!非常感谢你。我需要一点时间来理解最后一行。太棒了!
猜你喜欢
  • 2022-07-09
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-02
  • 2011-12-27
  • 2011-04-17
相关资源
最近更新 更多