我正在創建一個包含單獨帖子的應用程序(類似於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