如何按多个条件对Swift对象进行排序

Mat*_*ger 5 sorting swift

我有一个Swift对象列表,我想按多个标准排序.列表中的对象类型为DateRange:

class DateRange {
    var from: NSDate?
    var to: NSDate?
}
Run Code Online (Sandbox Code Playgroud)

该列表包含许多这些对象,其中一些fromto字段为零.我希望这个列表排序依据:

  1. 首先是所有具有日期的对象
  2. 然后具有对象的至少一个日期(无论是fromto)
  3. 而在最后的对象没有任何

日期本身并不重要,只是它们的存在.在Ruby中,我可以这样做(如果日期是nil我将它设置为一个非常低的日期):

date_ranges.sort { |a, b|
  [fix_nil(a.from), fix_nil(a.to)] <=> [fix_nil(b.from), fix_nil(b.to)]
}.reverse

def fix_nil(val)
  val.nil? ? Date.new(0) : val
end
Run Code Online (Sandbox Code Playgroud)

使用Swift的最佳方法是什么?提前致谢.

Nat*_*ook 2

似乎dateCount向您的DateRange类型添加计算属性可能是个好主意。这将是模式匹配的好时机:

extension DateRange {
    // returns the number of non-nil NSDate members in 'from' and 'to'
    var dateCount: Int {
        switch (from, to) {
        case (nil, nil): return 0
        case (nil, _): return 1
        case (_, nil): return 1
        default: return 2
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用一个简单的闭包对列表进行排序:

var ranges = [DateRange(nil, nil), DateRange(NSDate(), nil), DateRange(nil, NSDate()), DateRange(nil, nil), DateRange(NSDate(), NSDate())]
ranges.sort { $0.dateCount > $1.dateCount }
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你甚至可以Comparable多写几行:

extension DateRange : Comparable { }
func ==(lhs: DateRange, rhs: DateRange) -> Bool {
    return lhs.dateCount == rhs.dateCount
}
func <(lhs: DateRange, rhs: DateRange) -> Bool {
    return lhs.dateCount > rhs.dateCount
}
Run Code Online (Sandbox Code Playgroud)

这使您可以使用运算符参数对列表进行正确排序:

ranges.sort(<)
Run Code Online (Sandbox Code Playgroud)