1

I have a NSDictionary. When I print it, it looks like this:

{
    3gZ0qtk0yMUEvtSmz2RW40Y7AC83 = 12;
    USXhV0QYkpbSzAmXgfeteXHuoqg2 = 25;
    UTPFBV5Q5IgTh17060c6WxNDQCO2 = 1;
    fqsspZtskWVheqUQQtROepixsGB2 = 256;
}

I want to sort it so that it looks like this:

{
    fqsspZtskWVheqUQQtROepixsGB2 = 256;
    USXhV0QYkpbSzAmXgfeteXHuoqg2 = 25;
    3gZ0qtk0yMUEvtSmz2RW40Y7AC83 = 12;
    UTPFBV5Q5IgTh17060c6WxNDQCO2 = 1;
}

All of the methods I see needs a key name but I don't understand that. There is no key name. Sorry if this is duplicate but everything I try from other questions doesn't work. There's just too many ways out there and I get all kinds of errors and other problems so I want to know the best (latest), and most efficient way to sort NSDictionaries in this way.

Also it's coming from a firebase snapshot example:

self.friendsDict = snapshot.value as! NSDictionary
Wayne Filkins
  • 494
  • 6
  • 20
  • check this : http://stackoverflow.com/questions/27639993/swift-sort-dictionary-by-value – Bista Sep 08 '16 at 09:21
  • 6
    Dictionaries are unsorted collections. Sorting them has no meaning. – Fogmeister Sep 08 '16 at 09:22
  • That didn't work, and it's NSDictionary, I think that was for some other type or something. – Wayne Filkins Sep 08 '16 at 09:26
  • Unlike Arrays, Dictionaries have no order. Every element is identified by a key ( a string ), in you case the jumbled text, unlike in arrays where instead of keys, they use index (order count) – Zayne ZH Sep 08 '16 at 09:28
  • why you want to sort dictionary because it has no meaning. you can retrieve any value by it's key so just no need to sort it! then also if you want to do then [this so post](http://stackoverflow.com/questions/24090016/sort-dictionary-by-values-in-swift) can help! – Ketan Parmar Sep 08 '16 at 09:37

2 Answers2

2

Since you said the solution from this link Swift sort dictionary by value didn't work, I am posting a working code on my side:

let dict:NSDictionary = [
    "3gZ0qtk0yMUEvtSmz2RW40Y7AC83" : 12,
    "USXhV0QYkpbSzAmXgfeteXHuoqg2" : 25,
    "UTPFBV5Q5IgTh17060c6WxNDQCO2" : 1,
    "fqsspZtskWVheqUQQtROepixsGB2" : 256
]

let d = dict as! [String:NSInteger]

for (k,v) in (Array(d).sort {$0.1 > $1.1}) {
    print("\(k):\(v)")
}

Output:

fqsspZtskWVheqUQQtROepixsGB2:256
USXhV0QYkpbSzAmXgfeteXHuoqg2:25
3gZ0qtk0yMUEvtSmz2RW40Y7AC83:12
UTPFBV5Q5IgTh17060c6WxNDQCO2:1

Edit:

For above code to work, OP had to change:

self.friendsDict = snapshot.value as! NSDictionary

to:

self.friendsDict = snapshot.value as! [String:NSInteger]
Community
  • 1
  • 1
Bista
  • 7,869
  • 3
  • 27
  • 55
  • 1
    yes, but he should first cast his `NSDictionary` to `[String: AnyObject]`. Just put `as! [String: AnyObject]` after your NSDictionary – S2dent Sep 08 '16 at 09:30
  • 1
    It's working for you because d isn't an NSDictionary. Can you tell me what d is, so maybe I can convert the NSDictionary to it, otherwise I'm trying to convert to array right now. Not sure which would be more efficient though. – Wayne Filkins Sep 08 '16 at 09:30
  • Okay S2dent is correct, that's why I was getting the error. – Wayne Filkins Sep 08 '16 at 09:30
  • @WayneFilkins also, there are no efficiency issues, they are directly bridged so they work like the same object – S2dent Sep 08 '16 at 09:31
  • with @WayneFilkins , I have updated the code. Btw, i am checked and worked with NSInteger. and changed to Descending order. – Bista Sep 08 '16 at 09:32
  • 1
    @Mr.UB OP want descending order so change `<` with `>`. – Nirav D Sep 08 '16 at 09:34
  • Strictly spoken you are sorting an array of tuples which loses the advantage of a real dictionary. – vadian Sep 08 '16 at 09:36
  • @vadian - I don't know why OP wanted it, i think he wants to added result into and array. – Bista Sep 08 '16 at 09:37
  • This isn't working, even with NSInteger it keeps saying "AnyObject is not convertible to String" – Wayne Filkins Sep 08 '16 at 09:37
  • Please add some code and let us see how the data is added to the dictionary. – Bista Sep 08 '16 at 09:39
  • it's a Firebase snapshot. example: self.friendsDict = snapshot.value as! NSDictionary – Wayne Filkins Sep 08 '16 at 09:41
  • Can you take `snapshot.value as! [String:NSInteger]` ? – Bista Sep 08 '16 at 09:45
  • @WayneFilkins Use Swift native collection types. It make things easier. – vadian Sep 08 '16 at 09:45
  • converted snapshot to String:NSInteger which seems okay but for the rest of the code I got an error: "missing argument label arrayLiteral: in call" – Wayne Filkins Sep 08 '16 at 09:50
  • 1
    Wait no I had declared friendsDict as NSDictionary, okay yup that worked! – Wayne Filkins Sep 08 '16 at 09:53
  • 1
    basically my mistake was ever converting it to nsdictionary. I think it's better to do the sorting this way, then I am hoping I can convert it to NSDictionary once it is sorted, because the rest of the code depends on it being of that type. – Wayne Filkins Sep 08 '16 at 09:56
  • I recommend changing it to basically include the snapshot part, being as! String:NSInteger, then doing the sorting, then maybe at the end you can convert to NSDictionary. I already selected it as correct but technically that won't work, you don't want it to be NSDictionary until after the sorting. – Wayne Filkins Sep 08 '16 at 09:58
  • You can edit my answer for other user's as future reference. – Bista Sep 08 '16 at 09:59
  • 1
    After converting it back to (NS)Dictionary it will be unsorted/unordered again, because as mentioned many times a dictionary is unordered by definition. – vadian Sep 08 '16 at 09:59
2

try this -

let dict:NSMutableDictionary = [
    "3gZ0qtk0yMUEvtSmz2RW40Y7AC83" : 12,
    "USXhV0QYkpbSzAmXgfeteXHuoqg2" : 25,
    "UTPFBV5Q5IgTh17060c6WxNDQCO2" : 1,
    "fqsspZtskWVheqUQQtROepixsGB2" : 256
]

let sortedKeys2 = (dict as NSDictionary).keysSortedByValueUsingComparator
    {
       ($1 as! NSNumber).compare($0 as! NSNumber)
}

OR

let dict = [
"3gZ0qtk0yMUEvtSmz2RW40Y7AC83" : 12,
"USXhV0QYkpbSzAmXgfeteXHuoqg2" : 25,
"UTPFBV5Q5IgTh17060c6WxNDQCO2" : 1,
"fqsspZtskWVheqUQQtROepixsGB2" : 256

]

var sortedKeys = Array(dict.keys).sort({dict[$0] > dict[$1]})
Anupam Mishra
  • 3,408
  • 5
  • 35
  • 63