2015-04-05 197 views
0

我正在創建一個包含單獨帖子的應用程序(類似於Instagram)。每篇文章都是位於一個大陣列中的字典。在每本詞典中,它們都是一個NSDate,我希望按照從最新到最舊的順序對詞典進行排序。詞典中的NSDates對字典排序

我已經閱讀過類似的問題,但他們是在客觀的C.我有一種感覺NSSortDescriptor是一種有用的方法,但我不確定如何在這種情況下使用它。

任何幫助將是巨大的,

感謝

回答

5

如果你在寫斯威夫特,你可能會發現它更容易使用雨燕數組類型([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)。

+0

非常感謝廣泛的答覆!但是,我確實有一個問題 - 數組中包含的所有字典都是。這意味着我的NSDate在到達排序部分時是一個字符串。通過警告引起我的注意 - 從NSString到NSDate的轉換總是失敗(除非格式正確)。我將如何去解決這個問題? – Matt 2015-05-20 07:27:45

+0

增加了一些代碼。 – 2015-05-20 18:46:59

+0

工作很好,非常感謝所有的幫助! – Matt 2015-05-21 11:40:46