-2

Currently, I have a nested dictionary declared as

var userSchedule = [String:[String:String]]()

I get results like:

["2": ["time": "tbd", "date": "1/15", "name": "Chris"], 
 "0": ["time": "6:16 PM", "date": "1/15", "name": "Bob"], 
 "1": ["time": "1:15PM", "date": "1/15", "name": "John"]]

I want to sort this result so that the results would be in order by the first key.

So:

["0": ["time": "6:16 PM", "date": "1/15", "name": "Bob"], 
 "1": ["time": "1:15PM", "date": "1/15", "name": "John"], 
 "2": ["time": "tbd", "date": "1/15", "name": "Chris"]]

How could I efficiently do this in Swift4? Please help!

ielyamani
  • 17,807
  • 10
  • 55
  • 90
Ralph Lee
  • 87
  • 2
  • 9
  • 5
    `Dictionary` is unordered, you can't sort it. Anyway, you can create `Array` from it – Robert Dresler Mar 21 '19 at 20:59
  • 1
    Dictionaries are unordered collection, so you can't sort it. You need to use some other collection and implement logic to convert this dictionary and sort it. Hint: Array of dictionary where each index represents the numeric value of it's corresponding dictionary key. – Midhun MP Mar 21 '19 at 21:02
  • 1
    I would suggest that you create structs rather than using dictionaries. You can then have an array of structs and sort that – Paulw11 Mar 21 '19 at 21:18
  • Possible duplicate of [How to sort Dictionary by keys where values are array of objects in Swift 4?](https://stackoverflow.com/questions/47148473/how-to-sort-dictionary-by-keys-where-values-are-array-of-objects-in-swift-4) – luckyging3r Mar 21 '19 at 21:33
  • Possible duplicate of [Sort Dictionary by keys](https://stackoverflow.com/questions/25377177/sort-dictionary-by-keys) – ielyamani Mar 22 '19 at 03:47

3 Answers3

0

Dictionary is unordered, you can't sort it.


But, in your case I would get rid of dictionary and I would have just array of your model.

Create custom struct which would represent your event and then you can sort your array by model's id property

struct Event {
    let time, date, name: String
    let id: Int
}

var userSchedule = [Event(time: "tbd", date: "1/15", name: "name", id: 2),
                    Event(time: "6:16 PM", date: "1/15", name: "Chris", id: 0),
                    Event(time: "1:15PM", date: "1/15", name: "John", id: 1)]

userSchedule.sort { $0.id < $1.id }

If you're for example getting your dictionary as response from server, you can use compactMap to remap it to array of Event

struct Event {
    let time, date, name: String
    let id: Int
}

var userSchedule = ["2": ["time": "tbd", "date": "1/15", "name": "Chris"],
                    "0": ["time": "6:16 PM", "date": "1/15", "name": "Bob"],
                    "1": ["time": "1:15PM", "date": "1/15", "name": "John"]]

var schedule = userSchedule.compactMap { (event) -> Event? in
    guard let time = event.value["time"], let date = event.value["date"], let name = event.value["name"], let id = Int(event.key) else { return nil }
    return Event(time: time, date: date, name: name, id: id)
}

schedule.sort { $0.id < $1.id }
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
0

Create a struct to hold the values and map your dictionary to an array of that struct

struct Schedule {
    let key: Int?
    let time: String?
    let date: String?
    let name: String?
}

var orderedSchedule = userSchedule.map { Schedule(key: Int($0.key), 
                                                  time: $0.value["time"], 
                                                  date: $0.value["date"], 
                                                  name: $0.value["name"]) }

orderedSchedule.sort { ($0.key ?? 0) < ($1.key ?? 0) }
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
0

You may do it this way: First sort it to an Array, then build an array with dictionary elements. It's simple as it only has two lines codes.

var userSchedule = ["2": ["time": "tbd", "date": "1/15", "name": "Chris"],
"0": ["time": "6:16 PM", "date": "1/15", "name": "Bob"],
"1": ["time": "1:15PM", "date": "1/15", "name": "John"]]

let userScheduleArray = userSchedule.sorted{$0.key < $1.key}

print(userScheduleArray) 
//[(key: "0", value: ["time": "6:16 PM", "date": "1/15", "name": "Bob"]), (key: "1", value: ["time": "1:15PM", "date": "1/15", "name": "John"]), (key: "2", value: ["time": "tbd", "date": "1/15", "name": "Chris"])]

let separatedDict = userScheduleArray.map{Dictionary(uniqueKeysWithValues: [$0])}

print(separatedDict)
//[["0": ["time": "6:16 PM", "date": "1/15", "name": "Bob"]], 
// ["1": ["time": "1:15PM", "date": "1/15", "name": "John"]], 
// ["2": ["time": "tbd", "date": "1/15", "name": "Chris"]]]

print(type(of: separatedDict))
//[[String:[String:String]]] i.e. Array<Dictionary<String, Dictionary<String, String>>> 
E.Coms
  • 11,065
  • 2
  • 23
  • 35