简体   繁体   中英

Sorting dictionary with DateComponents keys in swift

Hi Guys I briefly explain my problem.

From my database I get an array of HistoryItem , a custom type that contains a simple Date property inside it:

struct HistoryItem {
     let date: Date
     let status: Status // Not important for my problem
}

I want to group this data by year and month , I thought the best way was a dictionary with key DateComponents :

// ungroupedHistory is already fetched and is of type [HistoryItem]

var groupedHistory: [DateComponents : [HistoryItem]]

groupedHistory = Dictionary(grouping: ungroupedHistory) { (historyItem) -> DateComponents in
     let calendar = Calendar.current
     let components = calendar.dateComponents([.year, .month], from: hisoryItem.date)
     return components
}

The result is as expected but the problem is that it is unsorted, and it is obvious that this is the case since the dictionary by definition is an unsorted collection.

How can i get a sorted by date copy of this dictionary?

I've tried something like this:

let sortedDict = groupedHistory.sorted {
       $0.key.date.compare($1.key.date) == .orderedDescending
}

But I just get an array with keys of type:

[Dictionary<DateComponents, [HistoryItem]>.Element]

Thanks in advance!

You need to do this in 2 steps, first get an array with the dictionary keys sorted

let sortedKeys = groupedHistory.keys.sorted {
    $0.year! == $1.year! ? $0.month! < $1.month! : $0.year! < $1.year!
}

and then use that array to access the values in your dictionary in a sorted manner

for key in sortedKeys {
    print(groupedHistory[key])
}

A dictionary is unordered by definition.

To get a sorted array you could create a wrapper struct

struct History {
    let components : DateComponents
    let items : [HistoryItem]
}

then sort the keys and map those to an array of History

let sortedKeys = groupedHistory.keys.sorted{($0.year!, $0.month!) < ($1.year!, $1.month!)}
let history = sortedKeys.map{History(components: $0, items: groupedHistory[$0]!)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM