【问题标题】:Sorting Array with specific order in Swift在 Swift 中按特定顺序对数组进行排序
【发布时间】:2021-02-10 06:01:41
【问题描述】:

我想在 swiftUI 中按特定顺序对数组进行排序

let list = ["A","B","A1","C","B1","AA"]

我试过了:

let sortedList = list.sorted{ $0.localizedStandardCompare($1) == .orderedAscending }
// Output : sortedList = ["A","A1","AA","B","B1","C"]

还有

let sortedList = list.sorted{ $0.parcoursNom < $1.parcoursNom }
// Output : sortedList = ["A","A1","AA","B","B1","C"]

预期:

sortedList = ["A","AA","B","C","A1","B1"]

如果以一个数字结束,那么在最后

【问题讨论】:

    标签: arrays swift sorting


    【解决方案1】:

    你需要一个自定义的排序函数

    let sortedList = list.sorted {
        switch ($0.last!.isNumber, $1.last!.isNumber) {
        case (true, false):
            return false
        case (false, true):
            return true
        default:
            return $0 < $1
        }
    }
    

    如果您需要处理可能的空字符串,请为此添加两个case,我们可以避免强制解包

    let sortedList = list.sorted {
        switch ($0.last?.isNumber, $1.last?.isNumber) {
        case (true, false):
            return false
        case (false, true):
            return true
        case (nil, _):
            return false
        case (_, nil):
            return true
        default:
            return $0 < $1
        }
    }
    

    【讨论】:

    • 我建议将这个switch 提取到一个函数中,并编写测试来测试true/false/nil 的所有9 种可能组合。编写可靠的逐个比较器(即正确,因为它们提供一致的偏序,如文档中所述)是非常具有挑战性的
    【解决方案2】:

    有时,尤其是在对元组进行排序时,能够“使布尔值具有可比性”会很有帮助。这样,您可以使用元组定位来赋予排序优先级。

    ["A","B","A1","C","B1","AA"].sorted {
      let comparables = { (string: String) in
        ( (string.last?.isNumber ?? false).comparable,
          string
        )
      }
    
      return comparables($0) < comparables($1)
    }
    
    public extension Bool {
      /// A way to compare `Bool`s.
      ///
      /// Note: `false` is "less than" `true`.
      enum Comparable: CaseIterable, Swift.Comparable {
        case `false`, `true`
      }
    
      /// Make a `Bool` `Comparable`, with `false` being "less than" `true`.
      var comparable: Comparable { .init(booleanLiteral: self) }
    }
    
    extension Bool.Comparable: ExpressibleByBooleanLiteral {
      public init(booleanLiteral value: Bool) {
        self = value ? .true : .false
      }
    }
    

    【讨论】:

    • 为什么选择 CaseIterable?
    • 这里没有用到,但我觉得这种类型,Bool本身应该有。
    • 为什么不简单地extension Bool: Comparable {public static func &lt; (lhs: Bool, rhs: Bool) -&gt; Bool {!lhs || rhs}}
    • 然后按{ ($0.last?.isNumber == true, $0) &lt; ($1.last?.isNumber == true, $1) }排序
    • 我赞成使 Bool Comparable 和比较元组的想法。 IMO 的实现比应有的复杂得多
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    相关资源
    最近更新 更多