Brandon Stillitano
Brandon Stillitano

Reputation: 1736

Sort Dictionary by Key (Date)

I'm creating a list of notes that I need to group by date and the display them sorted by that date. For the data structure to support this I have a dictionary like this:

var sortedDictionary: [Date: [String]] = [:]

I've tried using sortedDictionary.sorted { $0.0 < $1.0 } but that returns a tuple and not a dictionary.

If anyone could provide some help on how I can either mutate that tuple back into a dictionary or just sort the dictionary using the keys which are dates it would be much appreciated.

Upvotes: 0

Views: 777

Answers (3)

Carlos Garc&#237;a
Carlos Garc&#237;a

Reputation: 1728

let whatYouGet: [Dictionary<Date, [String]>.Element] = unsortedDictionary
                                                         .sorted { $0.0 < $1.0 }
whatYouGet.forEach { print("\($0.key): \($0.value)") } // you search this

BTW: Dictionary orders are not reliables

From Swift's Dictionary Documentation:

The order of key-value pairs in a dictionary is stable between mutations but is otherwise unpredictable. If you need an ordered collection of key-value pairs and don’t need the fast key lookup that Dictionary provides, see the KeyValuePairs type for an alternative.

In addition, Swift structs are retained unless their internal values change, an reorder maintains these values, when you assign the reorder dict to other var/let, swift give the reference to first struct

Upvotes: 0

vadian
vadian

Reputation: 285200

Dictionaries are unordered by definition.

You could map the dictionary to a (array of) struct which can be sorted

struct Section {
    let date : Date
    let notes : [String]
}

let sections = groupedDictionary.map{Section(date: $0.key, notes: $0.value}.sorted{$0.date < $1.date}

Upvotes: 1

imike
imike

Reputation: 5656

Yeah dictionaries are unordered by definition, but you could create a sorted array of dictionary keys

let dict: [Date: [String]] = [:]
let sortedKeys = dict.keys.sorted { $0 < $1 }

and then e.g. use these sorted keys in the tableView's dataSource as a section

extension NotesViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return sortedKeys.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dict[sortedKeys[section]]?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let value = dict[sortedKeys[indexPath.section]]?[indexPath.row] 
            else { return UITableViewCell() }

        return UITableViewCell()
    }

Hope this example could help you

Upvotes: 2

Related Questions