6
votes

Trying to sort an NSMutableDictionary in Swift 3, code from Swift 2 doesn't work for me anymore (various errors).

I am trying to use the following code to sort my dictionary by its values, which are floats:

var sortedDict = unsortedDict.allValues.sorted({ $0 < $1 }).flatMap({ floatedlotterydictionary[$0] })

Essentially, I want this unsorted dictionary...

{
a = "1.7";
b = "0.08";
c = "1.4";
}

...to turn into this sorted dictionary...

{
b = "0.08";
c = "1.4";
a = "1.7";
}

But using that line of code from above returns the error "argument type anyobject does not conform with type NSCopying" for the $0 < $1 part. So how can I sort a dictionary by its values in Swift 3?

(Note: That line of code came in part from this answer.)

I am using Swift 3 in Xcode 8 beta 1.

2
A dictionary is unordered by definition. It is impossible to get your requested result as a dictionary. And don't use NSMutableDictionary in Swift. It is not related to the Swift Dictionary at all.vadian
And yes, I understand a dictionary is unordered...but I want it ordered ;). And though it is somewhat unrelated, what's wrong with it?owlswipe

2 Answers

7
votes

Ok. The collection methods available on a normal dictionary are still available, however the type of objects is not enforced, which adds an inherit unsafely.

In the docs the sorted takes a closure which lets us access the key and value at the same time and consider it as one element and hence sort your dictionary.

let k: NSMutableDictionary = ["a" : 1.7, "b" : 0.08, "c" : 1.4]
print(k.sorted(isOrderedBefore: { (a, b) in (a.value as! Double) < (b.value as! Double) }))

The casting is required, as the type of a.value and b.value is AnyObject. This works on my computer, running Xcode Version 8.0 beta (8S128d).

4
votes

There's also this way:

let k = ["a" : 1.7, "b" : 0.08, "c" : 1.4]

print(k.flatMap({$0}).sort { $0.0.1 < $0.1.1 })