希望根据该对象的date属性找出一种更清晰的Swifty方法来将对象数组转换为dictionay
。
仅关注日期,即2015年12月31日 - 没有时间比较。
所以,如果很多事情有5件事都有2015年12月31日的日期,那么这个词。将有一个项目日期和与该数据相关联的5个事物的数组。
例如
struct Thing {
var name:String
var date:NSDate
}
let manyThings = [Thing]()
目前我使用String
作为词典,让它有效。键。但肯定有很好的快速方法可以做到这一点。
func dateGroup(things:[Thing]) -> [String:[Thing]] {
var sameDays = [String:[Thing]]()
// sort into Dates, using local date string as filter
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
dateFormatter.timeZone = NSTimeZone()
for aThing in things {
let localDate = dateFormatter.stringFromDate(aThing.date)
if var thingsForDay = sameDays[localDate] {
thingsForDay.append(aThing)
sameDays[localDate] = thingsForDay
}
else {
var empty = [Thing]()
empty.append(aThing)
sameDays[localDate] = empty
}
}
}
答案 0 :(得分:2)
您可以使用数组上的reduce
函数将其转换为Dictionary
。这可以说更像是一种功能性方法,可能使其成为一种不错的Swift
方式。
func dateGroup(things:[Thing]) -> [String:[Thing]] {
// sort into Dates, using local date string as filter
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
dateFormatter.timeZone = NSTimeZone()
return things.reduce([:]) { (reduction, aThing) -> [String:[Thing]] in
let localDate = dateFormatter.stringFromDate(aThing.date)
var result = reduction
if var thingsForDay = result[localDate] {
thingsForDay.append(aThing)
result[localDate] = thingsForDay
}
else {
result[localDate] = [aThing]
}
return result
}
}
仅供参考。 Swift
中的大多数集合中有一些方法我认为是在这个阵营中。有filter()
,map()
和reduce()
。 filter()
的使用是相当明显的,它基于一些返回Bool
的闭包为您提供了一个集合的子集。 map()
函数用于将集合转换为另一个集合,其中每个元素都转换为其他元素。 reduce()
函数用于将某些集合转换为某些结果(在这种情况下,该结果是原始集合的子Dictionary
的{{1}}。
答案 1 :(得分:1)
我还使用了reduce
,另外,我使用??
运算符来清理if条件。
func dateGroup(things:[Thing]) -> [String:[Thing]] {
// sort into Dates, using local date string as filter
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
dateFormatter.timeZone = NSTimeZone()
return things.reduce([:]) {
(var sameDays, aThing) in
let date = dateFormatter.stringFromDate(aThing.date)
sameDays[date] = (sameDays[date] ?? []) + [aThing]
return sameDays
}
}
适用于iOS 7及以下版本
func dateByRemovingTimeFromDate(date: NSDate) -> NSDate {
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([.Year, .Month, .Day], fromDate: date)
return calendar.dateFromComponents(components)!
}
func dateGroup(things:[Thing]) -> [NSDate:[Thing]] {
return things.reduce([:]) {
(var sameDays, aThing) in
let date = dateByRemovingTimeFromDate(aThing.date)
sameDays[date] = (sameDays[date] ?? []) + [aThing]
return sameDays
}
}
对于iOS 8及以上版本dateByRemovingTimeFromDate
可以简化
func dateByRemovingTimeFromDate(date: NSDate) -> NSDate {
return NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: date, options: [])!
}