你如何在字典中排序日期?

时间:2015-04-10 02:23:26

标签: swift

我在尝试对以下字典进行排序时遇到问题,以便在打印时以最早的日期第一顺序打印。

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,

            ]

4 个答案:

答案 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,它们应该正确排序。

首先,请假设您可以在字典中重新排列键值对。