按键排序字典

164

我想在Swift中对一个字典进行排序。 我有一个类似于以下的字典:

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

等等,我希望它像这样

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

我在 Stack Overflow 上尝试了许多解决方案,但没有一个适用于我。我正在使用 XCode6 Beta 5,在它上面有些方法会出现编译错误,有些解决方案会引发异常。所以,如果有人能够发布一个可用的字典排序代码,请帮忙。


10
字典是一种关联容器,无法对其进行排序。如果需要特定顺序,请将键复制到数组中并对其进行排序。然后迭代键,并获取相应的值。 - Sergey Kalinichenko
@dasblinkenlight,你能告诉我如何在Swift中对数组进行排序吗? - Aleem Ahmad
@dasblinkenlight 我已经尝试过了,但是在 [KeyType] 上出现了错误。 - Aleem Ahmad
@AleemAhmad 这是因为您需要将 KeyType 替换为您特定字典中键的类型(看起来您正在使用字符串)。 - Sergey Kalinichenko
显示剩余3条评论
16个回答

3

在iOS 9 & xcode 7.3,swift 2.2中,“sorted”是不可能的,需要将“sorted”更改为“sort”,就像这样:

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的结果不是字典,而是数组! - Channel
2
结果是一个由元组组成的数组,而不是一个字典 - user4886069

2

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

16
这不会返回一个字典,而是会返回一个元组的数组。 - anoop4real
2
你连问题都不看就回答了吗?这浪费了很多人的时间。这个问题特别是关于对字典进行排序并获得一个排序后的字典,而不是数组。我不知道为什么每个人都在提供错误的答案。 - Shivam Pokhriyal

1

Swift 3已按(by:<)排序

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

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

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
现在说点更严肃的:字典没有顺序。你的代码得到的是一个元组数组,而不是已排序的字典 - 正如一些答案和评论中已经提到的那样。 - Eric Aya
按键排序字典,我在回答这个话题。这只是关于Swift 3中语法更改的特定备注,它并不否认之前所写的任何内容。 - Joeri
这个答案相当不完整。sortedDict是什么?menu是什么?此代码似乎也无效。-cale_b。答案已经被编辑,唯一缺少的是一个字典声明-menu。我认为这很清楚,这只涉及到Swift 3中的语法更改。该代码在Swift 3中确实有效。 - Joeri
请问有关于Swift 4的任何建议吗? - famfamfam

0

按键排序的Swift字典

由于Dictionary[关于]是基于哈希函数的,因此无法像我们通常使用的那样使用排序函数(如Array)。作为替代方案,您可以实现一种类似于Java TreeMap/TreeSet的方式。

最简单的方法是使用.sorted(by:)函数。它返回一个已排序的key/value元组的Array,易于处理。

例如:

struct Person {
    let name: String
    let age: Int
}

struct Section {
    let header: String
    let rows: [Int]
}

let persons = [
    Person(name: "A", age: 1),
    Person(name: "B", age: 1),
    Person(name: "C", age: 1),
    Person(name: "A", age: 2),
    Person(name: "B", age: 2),
    Person(name: "C", age: 2),
    Person(name: "A", age: 3),
    Person(name: "B", age: 3),
    Person(name: "C", age: 3),
]

//grouped
let personsGroupedByName: [String : [Person]] = Dictionary(grouping: persons, by: { $0.name })
/**
 personsGroupedByName
 [0] = {
   key = "B"
   value = 3 values {
     [0] = (name = "B", age = 1)
     [1] = (name = "B", age = 2)
     [2] = (name = "B", age = 3)
   }
 }
 [1] = {
   key = "A"
   value = 3 values {
     [0] = (name = "A", age = 1)
     [1] = (name = "A", age = 2)
     [2] = (name = "A", age = 3)
   }
 }
 [2] = {
   key = "C"
   value = 3 values {
     [0] = (name = "C", age = 1)
     [1] = (name = "C", age = 2)
     [2] = (name = "C", age = 3)
   }
 }
 */

//sort by key
let sortedPersonsGroupedByName: [Dictionary<String, [Person]>.Element] = personsGroupedByName.sorted(by: { $0.0 < $1.0 })
/**
 sortedPersonsGroupedByName
 [0] = {
     key = "A"
     value = 3 values {
       [0] = (name = "A", age = 1)
       [1] = (name = "A", age = 2)
       [2] = (name = "A", age = 3)
     }
   }
   [1] = {
     key = "B"
     value = 3 values {
       [0] = (name = "B", age = 1)
       [1] = (name = "B", age = 2)
       [2] = (name = "B", age = 3)
     }
   }
   [2] = {
     key = "C"
     value = 3 values {
       [0] = (name = "C", age = 1)
       [1] = (name = "C", age = 2)
       [2] = (name = "C", age = 3)
     }
   }
 */

//handle
let sections: [Section] = sortedPersonsGroupedByName.compactMap { (key: String, value: [Person]) -> Section in
    let rows = value.map { person -> Int in
        return person.age
    }
    return Section(header: key, rows: rows)
}
/**
 sections
 [0] = {
     header = "A"
     rows = 3 values {
       [0] = 1
       [1] = 2
       [2] = 3
     }
   }
   [1] = {
     header = "B"
     rows = 3 values {
       [0] = 1
       [1] = 2
       [2] = 3
     }
   }
   [2] = {
     header = "C"
     rows = 3 values {
       [0] = 1
       [1] = 2
       [2] = 3
     }
   }
 */

-1

个人意见,因为所有答案似乎都没有注意到我们有一个字典,并且我们确实想要一个字典:

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

let sortedMenu = menu.sorted(by: <) // is an ARRAY
print(type(of: sortedMenu))


let sortedDict = Dictionary( uniqueKeysWithValues: menu.sorted(by: <) )
print(type(of: sortedDict))

以上我按值和键进行了排序:

让我们按照键来排序:

let sorted1 = menu.sorted { (kv1, kv2) in return kv1.key < kv2.key } 或者使用构造函数将其转换为字典。


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