如果您使用 Swift 编写代码,您可能会发现使用 Swift 数组类型 ([ContainedType]) 比使用 NSArray 更容易。除此之外,对 Swift 数组进行排序比使用 NSSortDescriptor 等更直接。
NSDates 可以像这样使用.compare 进行比较:
let d1 = NSDate()
let d2 = NSDate()
d1.compare(d2) == .OrderedAscending
但您可能更希望它们实现Comparable 协议,可以这样完成:
extension NSDate: Comparable { }
public func ==(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.isEqualToDate(rhs)
}
public func <(lhs: NSDate, rhs: NSDate) -> Bool {
return lhs.compare(rhs) == .OrderedAscending
}
// now you can do
d1 > d2
d1 <= d2 //etc
这样,您可以对日期数组进行排序:
let arr = [d2, d1]
let sortedArr = arr.sorted(<) // or > for descending order
如果您有日期字典,则需要从字典中获取日期值并进行比较,但这很容易:
let dicts = [["Date":d2], ["Date":d1]]
// pass sorted a function that compares two candidates in the array
dicts.sorted { lhs, rhs in
// even though dictionary lookups return optionals,
// this is fine because < is defined for optionals of Comparables
// (nil is < anything else)
lhs["Date"] < (rhs["Date"]
}
除了……你实际上没有[String:NSDate] 的数组——你可能有一堆不同的类型,它实际上是一个[String:AnyObject],所以你需要转换类型:
// dictionaries contain various different kind of values
let dicts: [[String:AnyObject]] = [["Date":d2], ["Date":d1]]
dicts.sorted { lhs, rhs in
(lhs["Date"] as? NSDate) < (rhs["Date"] as? NSDate)
}
但话虽如此,此时您可能想要考虑将数据存储为不作为内容字典,而是作为适当的数据结构:
struct Post {
let timestamp: NSDate
// and various other properties...
}
let posts: [Post] = [
Post(timestamp: d1),
Post(timestamp: d2)
]
posts.sorted { $0.timestamp < $1.timestamp }
编辑:您的评论提到您实际上有一本 [String:String] 类型的字典。这意味着您需要在比较它们之前以某种方式将字符串转换为日期。在这种情况下,您可以使用 NSDateFormatter 作为比较的一部分进行转换。一些示例代码:
let dicts: [[String:String]] = [["Date":"May 20 20015"], ["Date":"May 20 2014"]]
let fmt = NSDateFormatter()
fmt.dateStyle = .MediumStyle
let sortedDicts = dicts.sorted { lhs, rhs in
lhs["Date"].flatMap(fmt.dateFromString) < rhs["Date"].flatMap(fmt.dateFromString)
}
因此,在进行比较时,取出日期字符串,然后使用格式化程序将其转换为NSDate,然后比较结果。
注意,这使用了flatMap - 这是因为dateFromString 本身返回一个可选项,而您不想要一个可选项,因此您需要将结果展平。
这样做的最大缺点是无法检测到无效日期。如果其中的日期格式错误(例如,月份和日期的顺序错误),dateFromString 将返回 nil,并且它会被排序到数组的开头。
另一个缺点是它变得非常低效。在进行此类处理之前,您最好将数据转换为更结构化的形式(例如,struct 和 NSDate 类型的成员变量)。