按键对字典排序


128

我想在Swift中对字典进行排序。我有一本字典,例如:

"A" => Array[]
"Z" => Array[]
"D" => Array[]

等,我希望它像

"A" => Array[]
"D" => Array[]
"Z" => Array[]

等等

我在SO上尝试了许多解决方案,但没有人为我工作。我正在使用XCode6 Beta 5,在它上面有一些正在给编译器错误,在一些解决方案中有例外。因此,任何可以发布字典排序工作副本的人。



6
您无法对字典进行排序,它是一个关联容器。如果需要特定顺序,请将键复制到数组中,然后对其进行排序。然后遍历键,并拉出它们的对应值。
dasblinkenlight 2014年

@dasblinkenlight那么,您能告诉我如何快速对数组进行排序吗?
Aleem Ahmad

@AleemAhmad看一下这个答案,它具有sortedKeys功能。
dasblinkenlight 2014年

@dasblinkenlight我已经尝试过了,但是它在[KeyType]上给出了错误
Aleem Ahmad

Answers:


167
let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(<) // ["A", "D", "Z"]

编辑:

上面代码中的排序数组仅包含键,而值必须从原始字典中检索。但是,'Dictionary'也是'CollectionType'(键,值)对的一对,我们可以使用全局'sorted'函数来获取包含键和值的排序数组,如下所示:

let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
println(sortedKeysAndValues) // [(A, [1, 2]), (D, [5, 6]), (Z, [3, 4])]

EDIT2:目前倾向于每月更改一次的Swift语法

let sortedKeys = Array(dictionary.keys).sort(<) // ["A", "D", "Z"]

sorted不推荐使用全局变量。


这为您提供了一系列键。数组缺少值。我猜您可以从字典中查找值。
StilesCrisis 2014年

2
你是对的。我刚刚编辑了该帖子,以提供一种解决方案,用于获取按键排序的(键,值)对数组。感谢您的评论。
Ivica M.

@IvicaM。你好!我了解如何按键对字典进行排序,但不了解如何对字典中的元素数组进行排序。请帮我。例如,私人var联系人:[((String,[User]))] = []
Alexander Khitev,2016年

5
雨燕3 = Array(dictionary.keys).sorted(by:<)
miff

4
从Swift 4开始,您可以编写let sortedKeys = dictionary.keys.sorted()
代码不同

113

斯威夫特2.0

Ivica M的答案的更新版本:

let wordDict = [
     "A" : [1, 2],
     "Z" : [3, 4],
     "D" : [5, 6]
]

let sortedDict = wordDict.sort { $0.0 < $1.0 }
print("\(sortedDict)") // 

迅捷3

wordDict.sorted(by: { $0.0 < $1.0 })

注意:

生成的类型是数组而不是字典,不要感到惊讶。字典无法排序!产生的数据类型是一个排序数组,就像@Ivica的答案一样。


26
这实际上返回的是[(String,[Int])]的数组,而不是字典
scord

4
实现的字典是未排序的,因此无论如何重新创建数据类型都没有多大意义。我最后只保存了一组排序键。
scord

我得到Binary operator > can not be compared to two Any`操作数。垂头丧气也不起作用
肖恩(Sean)

27

如果要按键排序顺序遍历键和值,则此格式非常简洁

let d = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

for (k,v) in Array(d).sorted({$0.0 < $1.0}) {
    println("\(k):\(v)")
}

排序是自定义方法还是什么?它在执行时显示错误
rikky

@rikkyG Swift 1:sortsorted。斯威夫特2:sort已经成为sortInPlace并且sorted已经成为sort
埃里克·艾雅

14

在Swift 4中,您可以更聪明地编写它:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })

3
感谢您的努力,但首先,“ let”不会构建代码,因此首先它必须为“ var”。然后,在编译成功之后,此代码将无法正常运行,并且无法对字典进行排序,因此在运行此代码之前和之后我都得到相同的结果。也许我遗漏了一些东西,但是请详细说明或更改代码。======= var d = [1:“ hello”,2:“ bye”,-1:“ foo”] print(d)->>>打印[2:“ bye”,-1:“ foo“,1:” hello“] d = [Int:String](uniqueKeysWithValues:d.sorted {$ 0.key <$ 1.key})print(d)->>> prints [2:” bye“,-1 :“ foo”,1:“ hello”]
KarimIhab

这是不可能的,因为当您将其转换回字典时,它将迅速变为无序集合,因为swift中的字典是无序集合developer.apple.com/documentation/swift/dictionary
Jaimin

12

我尝试了以上所有内容,简而言之,您需要做的就是

let sorted = dictionary.sorted { $0.key < $1.key }
let keysArraySorted = Array(sorted.map({ $0.key }))
let valuesArraySorted = Array(sorted.map({ $0.value }))


6

对于Swift 4,以下对我有用:

let dicNumArray = ["q":[1,2,3,4,5],"a":[2,3,4,5,5],"s":[123,123,132,43,4],"t":[00,88,66,542,321]]

let sortedDic = dicNumArray.sorted { (aDic, bDic) -> Bool in
    return aDic.key < bDic.key
}

5
这不会返回字典,而是会返回一个元组数组
Daniel Arantes Loverde 18'Apr

@DanielArantesLoverde字典根据定义无法排序。元组数组是您可以做的最好的事情。
约翰·蒙哥马利

1
我知道,但是这个问题要求有序,所以这个答案是不正确的。你同意吗?
Daniel Arantes Loverde '18年

6

这是对字典本身进行排序的一种很好的替代方法:

从Swift 4和5开始

let sortedKeys = myDict.keys.sorted()

for key in sortedKeys {
   // Ordered iteration over the dictionary
   let val = myDict[key]
}

5

Swift 5中,为了按KEYS对Dictionary进行排序

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.0 < $1.0 })

为了按VALUES对Dictionary进行排序

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.1 < $1.1 })

4

对于Swift 3,以下排序可通过键返回排序后的字典:

let unsortedDictionary = ["4": "four", "2": "two", "1": "one", "3": "three"]

let sortedDictionary = unsortedDictionary.sorted(by: { $0.0.key < $0.1.key })

print(sortedDictionary)
// ["1": "one", "2": "two", "3": "three", "4": "four"]

10
这不会返回字典,这将返回一个元组数组
anoop4real

您甚至在提出答案之前都不会阅读问题。您在这里浪费很多人的时间。这个问题专门用于对字典进行排序并获得排序后的字典而不是数组。我不知道为什么每个人都回答错误。
Shivam Pokhriyal,

3

在iOS 9和xcode 7.3中无法进行“排序”,因此无法使用swift 2.2,将“已排序”更改为“已排序”,如下所示:

let dictionary = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]
let sortedKeysAndValues = Array(dictionary).sort({ $0.0 < $1.0 })
print(sortedKeysAndValues)

//sortedKeysAndValues = ["desert": 2.99, "main course": 10.99, "salad": 5.99]

3
sortedKeysAndValues的结果不是字典,而是数组!
2016年

2
其结果是一个ArrayTuples,而不是一个Dictionary

2

斯威夫特5

输入您要按字母顺序排序的字典。

// Sort inputted dictionary with keys alphabetically.
func sortWithKeys(_ dict: [String: Any]) -> [String: Any] {
    let sorted = dict.sorted(by: { $0.key < $1.key })
    var newDict: [String: Any] = [:]
    for sortedDict in sorted {
        newDict[sortedDict.key] = sortedDict.value
    }
    return newDict
}

dict.sorted(by:{$ 0.key <$ 1.key})本身返回一个元组(值,值),而不是字典 [value:value]。因此,for循环解析该元组以作为字典返回。这样,您放入字典并找回字典。


2

斯威夫特4&5

对于字符串键排序:

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

例:

var dict : [String : Any] = ["10" : Any, "2" : Any, "20" : Any, "1" : Any]

dictionary.keys.sorted() 

["1" : Any, "10" : Any, "2" : Any, "20" : Any]

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

["1" : Any, "2" : Any, "10" : Any, "20" : Any]


1

对于Swift 3,以下内容对我有效,而Swift 2语法无效:

// menu is a dictionary in this example

var menu = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]

let sortedDict = menu.sorted(by: <)

// without "by:" it does not work in Swift 3

这个答案还很不完整。什么sortedDict啊 什么menu啊 该代码也似乎无效。
random_user_name

现在更严重的事情是:字典没有顺序。您的代码得到的是一个元组数组,而不是一个排序的字典-正如在某些答案和注释中已经说过的那样。
埃里克·艾雅

主题是:按键对字典排序,我正在回答这个主题。这是只涉及Swift 3中语法更改的特定说明,它并不否认以前编写的内容。
Joeri

“这个答案很不完整。什么是sortedDict?什么是菜单?该代码也似乎无效。– cale_b”答案已被编辑,唯一缺少的是字典的声明-菜单。我认为很明显,这只是关于Swift 3中语法的更改。该代码确实可以在Swift 3中工作
。– Joeri

有任何关于迅速4 plz的建议吗?
famfamfam

1

Swift 3排序(按:<)

let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.