按Swift中的值排序字典

时间:2014-06-06 20:19:15

标签: swift

是否有模拟 - (NSArray *)keysSortedByValueUsingSelector :( SEL)比较器在swift?

如何在不转换为NSDictionary的情况下执行此操作?

我试过这个,但似乎不是一个好的解决方案。

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)

19 个答案:

答案 0 :(得分:26)

只需一行代码即可按Swift 4中的值对字典进行排序:

<a href="mailto:info@atmox.nl">info@atmox.nl</a>

答案 1 :(得分:21)

你可以使用这样的东西:

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"]

答案 2 :(得分:20)

尝试:

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中排序语义。请注意,我使用sort而不是sorted来最小化数组复制。通过查看早期版本并将sort替换为sorted并将KeyType[]修改为[KeyType]

,可以使代码更加紧凑

更新为Swift 2.2:

将类型从KeyType更改为KeyValueType更改为Value。使用新sort内置到Array代替sort(Array)注意使用sortInPlace代替sort

可以略微提高所有这些内容的效果

答案 3 :(得分:14)

这应该根据值给你排序的键,并且更清洁一点:

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

答案 4 :(得分:7)

我认为这是按值对Swift字典进行排序的最简单方法。

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)

答案 5 :(得分:5)

按字典的值对键进行排序实际上比最初看起来更简单:

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

就是这样!真的没什么了不起的。我还没有找到一种更快捷的方法。

答案 6 :(得分:5)

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

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

请注意使用flatMap,因为下载字典会返回一个可选值。在实践中,这应该永远不会返回nil,因为我们从字典本身获取密钥。 flatMap只是为了确保结果不是一个选项数组。如果您的数组的关联值应该是可选的,则可以使用map代替。

答案 7 :(得分:5)

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

使用.forEach - &gt;换掉.map功能编程

句法糖:

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

答案 8 :(得分:4)

通过键或值对字典进行排序

使用 Swift 5.2 内部处理“已排序”:

var unsortedDict = ["cola" : 10, "fanta" : 12, "sprite" : 8]

// sorting by value
let sortedDictByValue = unsortedDict.sorted{ $0.value > $1.value } // from lowest to highest using ">"
print("sorted dict: \(sortedDictByValue)")
// result: "sorted dict: [(key: "fanta", value: 12), (key: "cola", value: 10), (key: "sprite", value: 8)]\n"

// highest value
print(sortedDictByValue.first!.key)  // result: fanta
print(sortedDictByValue.first!.value)  // result: 12
// lowest value
print(sortedDictByValue.last!.key)  // result: sprite
print(sortedDictByValue.last!.value)  // result: 8
// by index
print(sortedDictByValue[1].key)  // result: cola
print(sortedDictByValue[1].value)  // result: 10

// sorting by key
let sortedDictByKey = unsortedDict.sorted{ $0.key < $1.key } // in alphabetical order use "<"
// alternative:
// let sortedDictByKey = unsortedDict.sorted{ $0 < $1 }  // without ".key"
print("sorted dict: \(sortedDictByKey)")
// result: "sorted dict: [(key: "cola", value: 10), (key: "fanta", value: 12), (key: "sprite", value: 8)]\n"

// highest value
print(sortedDictByKey.first!.key)  // result: cola
print(sortedDictByKey.first!.value)  // result: 10
// lowest value
print(sortedDictByKey.last!.key)  // result: sprite
print(sortedDictByKey.last!.value)  // result: 8
// by index
print(sortedDictByKey[1].key)  // result: fanta
print(sortedDictByKey[1].value)  // result: 12

答案 9 :(得分:4)

如果您希望输出是元组形式的键值对数组,按值排序,则以下内容可能很有用。

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)]

答案 10 :(得分:3)

将其强制转换为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) 
                  }

答案 11 :(得分:3)

从Swift 3开始,为了根据值对键进行排序,下面看起来很有希望:

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

答案 12 :(得分:2)

var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]

let arr = dic.sort{ (d1,d2)-> Bool in
if d1.value > d2.value {
    retrn true
}

}.map { (key,value) -> Int in
return value
}

采用一种干净的实现方式。 print(“ arr is:(arr)”)

答案 13 :(得分:1)

Swift 3中的以下方式按升序对值进行排序:

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

答案 14 :(得分:1)

使用字典作为值对字典进行排序(嵌套字典)

   var students: [String: [String: Any?]] = ["16CSB40" : ["Name": "Sunitha", "StudentId": "16CSB40", "Total": 90], "16CSB41" : ["Name": "Vijay", "StudentId": "16CSB40", "Total": 80], "16CSB42" : ["Name": "Tony", "StudentId": "16CSB42", "Total": 95]] // Sort this dictionary with total value

    let sorted = students.sorted { (($0.1["Total"] as? Int) ?? 0) < (($1.1["Total"] as? Int) ?? 0) }

    print(sorted) //Sorted result

答案 15 :(得分:1)

SWIFT 3:

使用一些资源我将这个精美的短代码放在一起。

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

这将返回按其值排序的字典键数组。它完美无缺。字典为空时不会抛出错误。在游乐场试试这段代码:

//: 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并且在“已排序”方法后甚至没有括号,请查看此帖子 - https://stackoverflow.com/a/34785745/7107094

答案 16 :(得分:0)

由于Swift 3.0 Dictionary具有sorted(by:)函数,该函数返回元组数组([(Key, Value)])。

let sorted = values.sorted(by: { (keyVal1, keyVal2) -> Bool in
    keyVal1.value > keyVal2.value
})

答案 17 :(得分:0)

这就是我的做法 - 在这种情况下通过一个名为position的键进行排序。在操场上试试这个:

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
}

答案 18 :(得分:0)

使用它,然后使用输出键再次遍历字典。

extension Dictionary where Value: Comparable {
  func sortedKeysByValue() -> [Key] {
    keys.sorted { return self[$0]! < self[$1]! }
  }
}

...或者如果您讨厌用力将其解开:)

extension Dictionary where Value: Comparable {
  func sortedKeysByValue() -> [Key] {
    keys.sorted { (key1, key2) -> Bool in
      guard let val1 = self[key1] else { return true }
      guard let val2 = self[key2] else { return true }
      return val1 < val2
    }
  }
}