Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 如何按多个条件对Swift对象进行排序_Sorting_Swift - Fatal编程技术网

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

Sorting 如何按多个条件对Swift对象进行排序,sorting,swift,Sorting,Swift,我有一个Swift对象列表,我想按多个条件进行排序。列表中的对象类型为DateRange: class DateRange { var from: NSDate? var to: NSDate? } 该列表包含许多这样的对象,其中一些from或to字段为零。我希望此列表按以下顺序排序: 首先是所有有日期的对象 然后是至少有一个日期的对象(从到或到) 在最末端,没有任何物体 日期本身并不重要,只是它们的存在。在Ruby中,我可以这样做(如果日期是nil我将其设置为非常低的日期):

我有一个Swift对象列表,我想按多个条件进行排序。列表中的对象类型为
DateRange

class DateRange {
    var from: NSDate?
    var to: NSDate?
}
该列表包含许多这样的对象,其中一些
from
to
字段为零。我希望此列表按以下顺序排序:

  • 首先是所有有日期的对象
  • 然后是至少有一个日期的对象(从<代码>到<代码>或<代码>到<代码>)
  • 在最末端,没有任何物体
  • 日期本身并不重要,只是它们的存在。在Ruby中,我可以这样做(如果日期是
    nil
    我将其设置为非常低的日期):

    date_ranges.sort{a,b|
    [固定零(a.from),固定零(a.to)][固定零(b.from),固定零(b.to)]
    }.反向
    def fix_nil(val)
    val.nil?新日期(0):val
    结束
    
    用斯威夫特做这件事最好的方法是什么?提前谢谢。

    我想你所说的列表是指数组,所以我的回答基于这个假设

    您可以使用数组结构的
    sort
    方法,该方法接受具有以下签名的闭包:

    (lhs: T, rhs: T) -> Bool 
    
    如果
    lhs
    小于
    rhs
    ,则返回
    true
    ,否则返回false

    我提出了这个实现:

    var x: [DateRange]
    // ... initialize the array
    
    x.sort { (lhs: DateRange, rhs: DateRange) -> Bool in
        if lhs.from != nil && lhs.to != nil {
            return true
        }
    
        if lhs.from == nil && lhs.to == nil {
            return false
        }
    
        return rhs.from == nil && rhs.to == nil
    }
    
    • 如果
      lhs
      两个属性都不是nil,那么不管
      rhs
    • 如果
      lhs
      同时具有两个属性nil,则无论
      rhs
    • else
      lhs
      有一个nil,另一个不是nil,在这种情况下,只有当
      rhs
      两个属性都为nil时,它才排在第一位
    如果您计划在多个地方重复使用
    排序
    ,最好将代码移出
    排序
    方法-最好的地方可能是
    操作符的重载:/p 预失效<(左:日期范围,右:日期范围)->Bool{ 如果lhs.from!=nil&&lhs.to!=nil{ 返回真值 } 如果lhs.from==nil&&lhs.to==nil{ 返回错误 } 返回rhs.from==nil&&rhs.to==nil } 在这种情况下,可按如下方式使用:

    x.sort(<)
    

    x.sort(以下是我的方法。为了保持简单,请为日期范围添加评分函数。在您的场景中,有3种可能性:

    零分&零分:0分

    无和日期:1分

    日期和日期:2分

    import Foundation
    
    class DateRange {
        var from: NSDate?
        var to: NSDate?
    
        init(from: NSDate?, to: NSDate?)
        {
            self.from = from
            self.to = to
        }
    
        func scoreDateRange() -> Int
        {
            var score = 0
            if from != nil
            {
                score++
            }
            if to != nil
            {
                score++
            }
            return score
        }
    }
    
    func sortDateRange( d1 : DateRange, d2 : DateRange)-> Bool
    {
    
        return d1.scoreDateRange() > d2.scoreDateRange()
    }
    
    var date_ranges = [DateRange]()
    date_ranges.append(DateRange(from:nil, to:nil))
    date_ranges.append(DateRange(from:nil, to:nil))
    date_ranges.append(DateRange(from:NSDate(), to:NSDate()))
    date_ranges.append(DateRange(from:nil, to:NSDate()))
    date_ranges.append(DateRange(from:NSDate(), to:nil))
    date_ranges.append(DateRange(from:NSDate(), to:NSDate()))
    
    date_ranges.sort(sortDateRange)
    

    似乎最好将
    dateCount
    computed属性添加到
    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
            }
        }
    }
    
    然后,您可以使用简单的闭包对列表进行排序:

    var ranges = [DateRange(nil, nil), DateRange(NSDate(), nil), DateRange(nil, NSDate()), DateRange(nil, nil), DateRange(NSDate(), NSDate())]
    ranges.sort { $0.dateCount > $1.dateCount }
    
    如果您愿意,您甚至可以通过增加几行代码使其具有可比性:

    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
    }
    
    扩展日期范围:可比较{}
    func==(左:日期范围,右:日期范围)->Bool{
    返回lhs.dateCount==rhs.dateCount
    }
    func Bool{
    返回lhs.dateCount>rhs.dateCount
    }
    
    这使您可以使用运算符参数对列表进行正确排序:

    ranges.sort(<)
    

    ranges.sort(我认为您的比较有一个bug——当比较两个相同的
    DateRange
    实例时,如果它们都是
    (nil,nil),这将返回true)
    。第二个if应该包括这一点:如果lhs都为nil,它返回false对不起——我倒过来了。如果两个范围都有两个日期,这将返回true,因为第一个条件只是查看
    lhs
    。感谢您的回答,特别是“就地”排序的提示。我现在使用
    sortBy
    函数ich可以很好地处理不可变的数据。评分功能的好主意,谢谢你的快速回答!
    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
    }
    
    ranges.sort(<)