按照Swift中的值对Dictionary进行sorting

是否有类似于 – (NSArray *)keysSortedByValueUsingSelector:(SEL)比较器在swift?

如何做到这一点,而不铸造到NSDictionary?

我尝试过,但似乎不是一个好的解决scheme。

var values = Array(dict.values) values.sort({ $0 > $1 }) for number in values { for (key, value) in dict { if value == number { println(key + " : \(value)"); dict.removeValueForKey(key); break } } } 

例:

 var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8] dict.sortedKeysByValues(>) // fanta (12), cola(10), sprite(8) 

尝试:

 let dict = ["a":1, "c":3, "b":2] extension Dictionary { func sortedKeys(isOrderedBefore:(Key,Key) -> Bool) -> [Key] { return Array(self.keys).sort(isOrderedBefore) } // Slower because of a lot of lookups, but probably takes less memory (this is equivalent to Pascals answer in an generic extension) func sortedKeysByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] { return sortedKeys { isOrderedBefore(self[$0]!, self[$1]!) } } // Faster because of no lookups, may take more memory because of duplicating contents func keysSortedByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] { return Array(self) .sort() { let (_, lv) = $0 let (_, rv) = $1 return isOrderedBefore(lv, rv) } .map { let (k, _) = $0 return k } } } dict.keysSortedByValue(<) dict.keysSortedByValue(>) 

更新:

更新到新的数组语法和从beta 3的sorting语义。请注意,我正在使用sort而不是sorted以最大限度地减less数组复制。 通过查看较早的版本,并通过sorted并将KeyType[]固定为[KeyType] ,可以使代码更加紧凑。

更新到Swift 2.2:

将types从KeyType更改为Key ,将ValueType更改为Value 。 使用新的sort内置Array而不是sort(Array)注意所有这些的性能可以通过使用sortInPlace而不是sort略有改善

你也许可以使用这样的东西:

 var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8] var myArr = Array(dict.keys) var sortedKeys = sort(myArr) { var obj1 = dict[$0] // get ob associated w/ key 1 var obj2 = dict[$1] // get ob associated w/ key 2 return obj1 > obj2 } myArr // ["fanta", "cola", "sprite"] 

这应该给你基于价值的sorting的键,是更清洁一点:

 var sortedKeys = Array(dict.keys).sorted({dict[$0] < dict[$1]}) 

通过字典的值对键进行sorting实际上比首先出现的要简单:

 let yourDict = ["One": "X", "Two": "B", "Three": "Z", "Four": "A"] let sortedKeys = yourDict.keys.sort({ (firstKey, secondKey) -> Bool in return yourDict[firstKey] < yourDict[secondKey] }) 

而就是这样! 没有什么比这更多的了。 我还没有find一个更快的方法。

我认为这是按值sortingSwift词典的最简单的方法。

 let dict = ["apple":1, "cake":3, "banana":2] let byValue = { (elem1:(key: String, val: Int), elem2:(key: String, val: Int))->Bool in if elem1.val < elem2.val { return true } else { return false } } let sortedDict = dict.sort(byValue) 

很多答案,这里是一个单线。 我喜欢它,因为它充分利用了原生的Swift迭代函数,并且不使用variables。 这应该有助于优化者发挥它的魔力。

 return dictionary.keys.sort({ $0 < $1 }).flatMap({ dictionary[$0] }) 

请注意使用flatMap,因为为字典下标会返回一个可选的值。 在实践中,由于我们从字典本身获得密钥,所以它不应该返回零。 flatMap只是为了确保结果不是可选的数组。 如果数组的相关值应该是可选的,则可以使用map来代替。

只需将其转换为NSDictionary,然后调用该方法。 任何你在ObjC中使用@selector的地方,你都可以在Swift中使用一个string。 所以它看起来像这样:

 var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8] let sortedKeys = (dict as NSDictionary).keysSortedByValueUsingSelector("compare:") 

要么

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

从Swift 3开始,根据数值对键进行sorting,下面看起来很有前途:

 var keys = Array(dict.keys) keys.sortInPlace { (o1, o2) -> Bool in return dict[o1]! as! Int > dict[o2]! as! Int } 

OneLiner:

 let dict = ["b":2,"a":1,"c":3] (Array(dict).sorted{$0.1 < $1.1}).forEach{(k,v) in print("\(k):\(v)")} //Output: a:1, b:2, c:3 

.map – >函数式编程.forEach

语法糖:

 extension Dictionary where Value:Comparable { var sortedByValue:[(Key,Value)] {return Array(self).sorted{$0.1 < $1.1}} } extension Dictionary where Key:Comparable { var sortedByKey:[(Key,Value)] {return Array(self).sorted{$0.0 < $1.0}} } ["b":2,"a":1,"c":3].sortedByKey//a:1, b:2, c:3 ["b":2,"a":1,"c":3].sortedByValue//a:1, b:2, c:3 

在Swift 3中按照以下方式按升序对值进行sorting:

 for (k,v) in (Array(dict).sorted {$0.1 < $1.1}) { print("\(k):\(v)") } 

SWIFT 3:

使用一些资源,我把这个简短的代码放在一起。

 dictionary.keys.sorted{dictionary[$0]! < dictionary[$1]!} 

这将返回按其值sorting的字典键的数组。 它完美的工作,不会抛出错误,当字典是空的。 在操场上试试这个代码:

 //: Playground - noun: a place where people can play import UIKit let dictionary = ["four": 4, "one": 1, "seven": 7, "two": 2, "three": 3] let sortedDictionary = dictionary.keys.sorted{dictionary[$0]! < dictionary[$1]!} print(sortedDictionary) // ["one", "two", "three", "four", "seven"] let emptyDictionary = [String: Int]() let emptyDictionarySorted = emptyDictionary.keys.sorted{emptyDictionary[$0]! < emptyDictionary[$1]!} print(emptyDictionarySorted) // [] 

如果你想得到一些帮助,为什么代码使用$ 0,$ 1,甚至没有括号在“sorting”的方法后,看看这篇文章 – https://stackoverflow.com/a/34785745/7107094

这就是我所做的 – 在这种情况下,通过一个叫做position的键来sorting。 在操场上试试这个:

 var result: [[String: AnyObject]] = [] result.append(["name" : "Ted", "position": 1]) result.append(["name" : "Bill", "position": 0]) result result = sorted(result, positionSort) func positionSort(dict1: [String: AnyObject], dict2: [String: AnyObject]) -> Bool { let position1 = dict1["position"] as? Int ?? 0 let position2 = dict2["position"] as? Int ?? 0 return position1 < position2 } 

如果您希望输出是一个元组forms的键值对(按值sorting),那么以下内容可能会很有用。

 var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8] let sortedArrByValue = dict.sorted{$0.1 > $1.1} print(sortedArrByValue) // output [(key: "fanta", value: 12), (key: "cola", value: 10), (key: "sprite", value: 8)]