【问题标题】:Sort an array based on the second value of a tuple根据元组的第二个值对数组进行排序
【发布时间】:2015-09-15 19:49:34
【问题描述】:

感谢您阅读我的帖子。

我有一个这样声明的元组数组:

var myArray: [(item1: String?, item2: NSDate?)] = []

在循环结束时,我想根据每个元组的 item2 对元组数组进行排序,其类型为 NSDate?

基于此answerthis answer,我尝试了以下操作,但收到此编译器错误"cannot invoke 'sort' with an argument list of type '((_,_) -> _)'

这是我尝试过的:

myArray.sort {$0.1.item2?.compare($1.1.item2?) == NSComparisonResult.OrderedDescending }

附: println() 工作正常并将 item1 和 item2 作为可选打印。

【问题讨论】:

  • 在数据结构中使用元组不是一个好习惯,而是使用数组或字典。来自 Apple Swift iBook:“元组对于相关值的临时组很有用。它们不适合创建复杂的数据结构。 如果您的数据结构可能在临时范围之外持续存在,请将其建模为类或结构,而不是元组。” 摘自:Apple Inc. “Swift 编程语言(Swift 2 Prerelease )。”电子书。 itun.es/us/k5SW7.l

标签: ios arrays swift sorting nsdate


【解决方案1】:

你必须实现 NSDate 的 Comparable 协议

public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs === rhs || lhs.compare(rhs) == .OrderedSame
}

public func <(lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedAscending
}

extension NSDate: Comparable { }

之后,您可以按日期对元组进行排序:

myArray!.sort {$0.1 == $1.1 ? $0.1 > $1.1 : $0.1 > $1.1 }

【讨论】:

  • 感谢您的回复。我刚刚尝试了你的解决方案,它没有用。 according here 我无法直接将 NSDate&lt; 进行比较。会不会是别的?
  • 是的,谢谢!但是@zaph 提到我应该考虑切换到数组或字典,所以我可能最终会这样做,所以我坚持良好的做法。感谢您的快速回复。
  • Swift 字典默认是不可排序的,所以如果你需要排序,最好实现这个结构的数组。
【解决方案2】:

公认解决方案的替代方案:

let res = myArray.sort { (left, right) -> Bool in
    return left.item2?.timeIntervalSinceReferenceDate < right.item2?.timeIntervalSinceReferenceDate
}

【讨论】:

    【解决方案3】:

    链接解决方案不起作用的原因是问题中定义的元组数组包含可选类型。

    检查选项可以解决问题,而无需向 NSDate 添加新的运算符。

    一个例子,有 3 个日期和可选类型:

    var myArray: [(item1: String?, item2: NSDate?)] = []
    myArray = [("now", NSDate()), ("now+30s", NSDate().dateByAddingTimeInterval(NSTimeInterval(30))), ("now-30s", NSDate().dateByAddingTimeInterval(NSTimeInterval(-30)))]
    
    myArray.sortInPlace { (lhs, rhs) -> Bool in
        if lhs.item2 != nil && rhs.item2 != nil {
            return lhs.item2!.compare(rhs.item2!) == .OrderedAscending
        }
        return false // Return true if you want nil values first
    }
    

    相同的代码,如果类型不允许可选:

    var myArray: [(item1: String, item2: NSDate)] = []
    myArray = [("now", NSDate()), ("now+30s", NSDate().dateByAddingTimeInterval(NSTimeInterval(30))), ("now-30s", NSDate().dateByAddingTimeInterval(NSTimeInterval(-30)))]
    
    myArray.sortInPlace { (lhs, rhs) -> Bool in
        return lhs.item2.compare(rhs.item2) == .OrderedAscending
    }
    

    MirekE 的解决方案也很有效,但您无法控制 nil 值的结束位置(它们将在开头)。

    【讨论】:

      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 2020-11-19
      • 2022-01-10
      • 2011-05-21
      • 2018-11-18
      • 2018-10-20
      • 2014-07-30
      • 1970-01-01
      相关资源
      最近更新 更多