按键值排序字典

11
let dict: [String:Int] = ["apple":5, "pear":9, "grape":1]

如何根据Int值对字典进行排序,以使输出结果为:

sortedDict = ["pear":9, "apple":5, "grape":1]

当前尝试 (排序不正确):

let sortedDict = sorted(dict) { $0.1 > $1.1 } 

1
字典本身没有排序顺序,它们是键值容器。 - vikingosegundo
1
请看:https://dev59.com/OmAf5IYBdhLWcg3w_Gyr - Lamour
@Emma,重新创建的字典如何能够有排序顺序? - vikingosegundo
@palpatim 我正在使用字典来存储一个带有关联投票计数的字符串。我想按最高>最低票(字典中的Int值)对值进行排序。 - Onichan
Emma,换句话说,你希望对字典中的值进行排序,而不是对字典本身进行排序。这是一个微妙的措辞变化,但是它对解决问题的思考方式产生了根本性的不同。@lamar上面的参考资料将为您提供有关按值对字典进行排序的一些指针。然后由您来构建一个按照您想要的顺序排列的键值对列表(例如数组)。 - Palpatim
显示剩余2条评论
4个回答

34
你需要对字典值进行排序,而不是键。可以按照如下方式从字典创建一个元组数组,并根据其值进行排序:

Xcode 9 • Swift 4Xcode 8 • Swift 3

let fruitsDict = ["apple": 5, "pear": 9, "grape": 1]
let fruitsTupleArray = fruitsDict.sorted{ $0.value > $1.value }

fruitsTupleArray // [(.0 "pear", .1 9), (.0 "apple", .1 5), (.0 "grape", .1 1)]

for (fruit,votes) in fruitsTupleArray {
    print(fruit,votes)
}

fruitsTupleArray.first?.key   // "pear"
fruitsTupleArray.first?.value   // 9

使用键来对字典进行排序

let fruitsTupleArray = fruitsDict.sorted{ $0.key > $1.key }
fruitsTupleArray  // [(key "pear", value 9), (key "grape", value 1), (key "apple", value 5)]

使用键和本地化比较对字典进行排序:

let fruitsTupleArray = fruitsDict.sorted { $0.key.localizedCompare($1.key) == .orderedAscending  }

编辑/更新:

我们还可以扩展Sequence协议并实现自定义排序,使用谓词进行排序,并使用键路径属性进行排序,只要它符合Comparable

extension Sequence {
    func sorted<T: Comparable>(_ predicate: (Element) -> T, by areInIncreasingOrder: ((T,T)-> Bool) = (<)) -> [Element] {
        sorted(by: { areInIncreasingOrder(predicate($0), predicate($1)) })
    }
}

用法:
let sortedFruitsAscending = fruitsDict.sorted(\.value)
print(sortedFruitsAscending)

let sortedFruitsDescending = fruitsDict.sorted(\.value, by: >)
print(sortedFruitsDescending)

将打印以下内容:

[(key: "grape", value: 1), (key: "apple", value: 5), (key: "pear", value: 9)]

[(key: "pear", value: 9), (key: "apple", value: 5), (key: "grape", value: 1)]


编辑/更新:

对于 Xcode 13 或更高版本,您可以使用一种名为 KeyPathComparator 的新通用结构:

let fruitsTupleArray = fruitsDict.sorted(using: KeyPathComparator(\.value, order: .reverse))

1
这就是我一直在寻找的答案。非常简单、易读和独立。适用于Swift 4.2和Xcode 10.1。非常感谢! - emreerokyar

3

字典不能被排序。通常,当我需要从字典中对东西进行排序时,我会单独创建一个由字典键组成的数组。

在您的情况下,可以先创建一个键的数组,通过比较它们在字典中的值来对它们进行排序。


0

使用 KeyValuePairs 而不是 Dictionary

"字典中键值对的顺序在变更之间是稳定的,但除此之外是不可预测的。如果您需要一个有序的键值对集合,并且不需要 Dictionary 提供的快速键查找功能,请参阅 KeyValuePairs 类型作为替代方案。" - Swift 字典


考虑到您无法为现有集合添加任何新值,因此这具有许多限制。 - Leo Dabus

0
可以通过以下实现来实现:

let sortedDictionary = unsortedDictionary.sorted{$0.key > $1.key}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接