我在尝试对以下字典进行排序时遇到问题,以便在打印时以最早的日期第一顺序打印。
var dayTotalDicTest: [String:Int] =
[
"04-09-2015" : 4,
"04-10-2015" : 6,
"04-07-2015" : 8,
"03-28-2015" : 10,
"12-10-2014" : 12,
"12-10-2015" : 12,
]
答案 0 :(得分:8)
编辑/更新:Xcode 8.2.1•Swift 3.0.2
extension String {
static let shortDateUS: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateStyle = .short
return formatter
}()
var shortDateUS: Date? {
return String.shortDateUS.date(from: self)
}
}
let dayTotalDicTest: [String:Int] = [
"04-09-2015" : 4,
"04-10-2015" : 6,
"04-07-2015" : 8,
"03-28-2015" : 10,
"12-10-2014" : 12,
"12-10-2015" : 12]
let myArrayOfTuples = dayTotalDicTest.sorted{
guard let d1 = $0.key.shortDateUS, let d2 = $1.key.shortDateUS else { return false }
return d1 < d2
}
print(myArrayOfTuples) // [("12-10-2014", 12), ("03-28-2015", 10), ("04-07-2015", 8), ("04-09-2015", 4), ("04-10-2015", 6), ("12-10-2015", 12)]\n"
for tuple in myArrayOfTuples {
print(tuple)
}
答案 1 :(得分:2)
在Swift 3中,Date对象现在具有可比性,我们可以按照以下方式完成您想要的任务:
let dayTotalDicTest: [String:Int] = [
"04-09-2015" : 4,
"04-10-2015" : 6,
"04-07-2015" : 8,
"03-28-2015" : 10,
"12-10-2014" : 12,
"12-10-2015" : 12]
//Create a date formatter to convert our date strings to Date objects
let df = DateFormatter()
df.dateFormat = "MM-dd-yyyy"
let sortedArrayOfDicts = dayTotalDicTest
//First map to an array tuples: [(Date, [String:Int]]
.map{(df.date(from: $0.key)!, [$0.key:$0.value])}
//Now sort by the dates, using `<` since dates are Comparable.
.sorted{$0.0 < $1.0}
//And re-map to discard the Date objects
.map{$1}
for item in sortedArrayOfDicts {
print(item)
}
上面的代码将键/值对一次映射到元组,其中第一个元素是Date对象,元组中的第二个条目是包含oringinal键/值对的单元素字典。然后它对元组数组进行排序,然后映射已排序的数组以提取键/值对,因此您剩下的是来自原始数据结构的单元素字典数组。
排序时,您希望在排序的比较操作期间避免昂贵的操作。将日期字符串转换为日期相当慢。在排序中的每次比较期间进行该转换都是效率低下的,因为您最终会将数组中的每个元素与多个其他元素进行比较,因此您反复进行字符串到目前的转换。
答案 2 :(得分:0)
无法对字典进行排序,因此您必须将其转换为数组。 map
函数可以为您完成。此外,字符串无法按提供的顺序排序,因此您需要将字符串重组为yyyy-MM-dd
格式,或将其转换为日期。
但是一旦你完成了,你就可以对数组进行排序。例如,使用Swift中的函数式编程,您可以执行以下操作,使用map
将字典转换为元组数组,然后使用sorted
对这些进行排序,使用{{1将字符串转换为日期:
NSDateFormatter
虽然它有一定的简单性,但它可能有点低效,比我们需要的更多地调用var dayTotalDictionary: [String:Int] = [
"04-09-2015" : 4,
"04-10-2015" : 6,
"04-07-2015" : 8,
"03-28-2015" : 10,
"12-10-2014" : 12,
"12-10-2015" : 12
]
let formatter = NSDateFormatter()
formatter.dateFormat = "MM-dd-yyyy"
let dayTotalArray = map(dayTotalDictionary) { ($0, $1) }
.sorted() { formatter.dateFromString($0.0)!.compare(formatter.dateFromString($1.0)!) == .OrderedAscending }
。所以,我可能让dateFromString
函数将map
对象添加到元组数组中,然后NSDate
可以利用已存在的sorted
对象:
NSDate
最终的let dayTotalArray = map(dayTotalDictionary) { (formatter.dateFromString($0)!, $0, $1) } // in Swift 2.0, use `dayTotalDictionary.map()`
.sorted() { ($0.0 as NSDate).compare($1.0 as NSDate) == .OrderedAscending } // in Swift 2.0, use `sort`
.map() { (_, dateString, dayTotal) in (dateString, dayTotal) }
拉出map
对象,但显然你不需要这样做,如果你可以将NSDate
保留在元组中。
答案 3 :(得分:-1)
您的日期是字符串,因此会根据string
排序规则对其进行排序。将格式更改为yyyy-MM-dd
,它们应该正确排序。
首先,请假设您可以在字典中重新排列键值对。