使用Swift 4.2,我试图找出对包含两个日期的对象进行排序的方法,以便最近的对象在数组中排在第一位。
我正在尝试以下操作,但由于以下原因而失败:
Binary operator '>=' cannot be applied to two '(Date?, Date?)' operands
。
let sortedSignComments = signComments.sorted(by: {
guard let serverDate0 = $0.serverLastUpdated else { return false }
guard let serverDate1 = $1.serverLastUpdated else { return false }
guard let clientDate0 = $0.clientLastUpdated else { return false }
guard let clientDate1 = $1.clientLastUpdated else { return false }
let lhs = (formatter.date(from: serverDate0), formatter.date(from: clientDate0))
let rhs = (formatter.date(from: serverDate1), formatter.date(from: clientDate1))
return lhs >= rhs
})
答案 0 :(得分:0)
我推荐
1-将class / struct用作模型而不是元组
2-将服务器&&客户端变量设为Date
/ timeStamp,当您使用格式化程序获取数据时将其填充
3-根据属性排序
您需要当前代码
return lhs.$0! >= rhs.$0! && lhs.$1! >= rhs.$1!
答案 1 :(得分:0)
现在看来效果很好。谢谢大家的帮助。
// fyi ref: @Martin R, https://stackoverflow.com/a/53427282/7599
func filterOptionalsWithLargeNil<T: Comparable>(lhs: T?, rhs: T?) -> T? {
var result: T?
switch (lhs, rhs) {
case let(l?, r?): result = l > r ? l : r // Both lhs and rhs are not nil
case let(nil, r?): result = r // Lhs is nil
case let(l?, nil): result = l // Lhs is not nil, rhs is nil
case (.none, .none):
result = nil
}
return result
}
...
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone.autoupdatingCurrent
formatter.dateFormat = DALconfig.ISO8601dateFormat
let sortedSignComments = signComments.sorted(by: {
// Convert ISO8601 date string format to Date() object.
let serverDate0: Date? = $0.serverLastUpdated != nil ? formatter.date(from: $0.serverLastUpdated!) : nil
let serverDate1: Date? = $1.serverLastUpdated != nil ? formatter.date(from: $1.serverLastUpdated!) : nil
let clientDate0: Date? = $0.clientLastUpdated != nil ? formatter.date(from: $0.clientLastUpdated!) : nil
let clientDate1: Date? = $1.clientLastUpdated != nil ? formatter.date(from: $1.clientLastUpdated!) : nil
// Filter and sort each object separately.
let objDate0: Date? = self.filterOptionalsWithLargeNil(lhs: serverDate0, rhs: clientDate0)
let objDate1: Date? = self.filterOptionalsWithLargeNil(lhs: serverDate1, rhs: clientDate1)
// Final comparison.
guard let finalDate0 = objDate0 else { return false }
guard let finalDate1 = objDate1 else { return false }
return finalDate0.compare(finalDate1) == .orderedDescending
})
结果:
答案 2 :(得分:0)
如果服务器和客户端始终处于同一时区(并且您不介意秋季夏令时),则可以对对象进行排序,而无需将字符串转换为日期。
如果对象数量很多,映射到可应用常规排序的可排序值将比映射N * Log(N)次更有效。
例如:
func getSortKey(obj:MyObject) -> Date { return .... }
sortedObjects = objectList.map{($0,getSortKey($0))}.sorted{$0.1>$1.1}.map{$0.0}
对于您的特定要求,getSortKey()函数可能需要从对象中选择两个日期之一,以便只有一个要比较的值。我猜您会希望按两个日期中的最新日期对对象进行排序,以便函数可以返回类似以下内容(伪代码):
var sortKey = Date.distantPast
if let serverDateString = obj.serverLastUpdated,
let serverDate = formatter.date(from: serverDateString)
{ sortKey = serverDate }
if let clientDateString = obj.clientLastUpdated,
let clientDate = formatter.date(from: clientDateString),
sortKey < clientDate
{ sortKey = clientDate }
return sortKey
如果您没有大量对象,则可以直接在排序中使用该函数:
sortedObjects = objectList.sorted{getSortKey($0)>getSortKey($1)}