我正在创建一个包含单独帖子的应用程序(类似于Instagram)。每篇文章都是位于一个大阵列中的字典。在每本词典中,它们都是一个NSDate,我希望按照从最新到最旧的顺序对词典进行排序。词典中的NSDates对字典排序
我已经阅读过类似的问题,但他们是在客观的C.我有一种感觉NSSortDescriptor
是一种有用的方法,但我不确定如何在这种情况下使用它。
任何帮助将是巨大的,
感谢
我正在创建一个包含单独帖子的应用程序(类似于Instagram)。每篇文章都是位于一个大阵列中的字典。在每本词典中,它们都是一个NSDate,我希望按照从最新到最旧的顺序对词典进行排序。词典中的NSDates对字典排序
我已经阅读过类似的问题,但他们是在客观的C.我有一种感觉NSSortDescriptor
是一种有用的方法,但我不确定如何在这种情况下使用它。
任何帮助将是巨大的,
感谢
如果你在写斯威夫特,你可能会发现它更容易使用雨燕数组类型([ContainedType]
)比NSArray
。除其他事项外,分拣斯威夫特阵列更直接不必使用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
,它会被排序到阵列的开始。
这另一个缺点是它变得非常低效。在进行这种处理之前,最好将数据转换为更加结构化的表单(例如,带有NSDate
型成员变量的struct
)。
非常感谢广泛的答复!但是,我确实有一个问题 - 数组中包含的所有字典都是。这意味着我的NSDate在到达排序部分时是一个字符串。通过警告引起我的注意 - 从NSString到NSDate的转换总是失败(除非格式正确)。我将如何去解决这个问题? –
Matt
2015-05-20 07:27:45
增加了一些代码。 – 2015-05-20 18:46:59
工作很好,非常感谢所有的帮助! – Matt 2015-05-21 11:40:46