2015-04-05 101 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