Swift中的有序字典

Joj*_*dmo 49 dictionary ios swift swift2

有没有内置的方法在Swift 2中创建有序地图?数组[T]按对象附加到它的顺序排序,但字典[K : V]不是有序的.

例如

var myArray: [String] = []
myArray.append("val1")
myArray.append("val2")
myArray.append("val3")

//will always print "val1, val2, val3"
print(myArray)


var myDictionary: [String : String] = [:]
myDictionary["key1"] = "val1"
myDictionary["key2"] = "val2"
myDictionary["key3"] = "val3"

//Will print "[key1: val1, key3: val3, key2: val2]"
//instead of "[key1: val1, key2: val2, key3: val3]"
print(myDictionary)
Run Code Online (Sandbox Code Playgroud)

是否有任何内置方法来创建一个有序的key : value映射,其顺序与数组相同,或者我是否必须创建自己的类?

如果可能的话,我想避免创建自己的类,因为Swift包含的内容很可能更有效.

Mun*_*ndi 32

只需使用一组元组.按你喜欢的方式排序.所有"内置".

var array = [(name: String, value: String)]()
// add elements
array.sort() { $0.name < $1.name }
// or
array.sort() { $0.0 < $1.0 }
Run Code Online (Sandbox Code Playgroud)

  • 这甚至没有接近有序地图.映射提供密钥唯一性和O(1)查找时间.这既不提供. (44认同)
  • @Lahav这就是我的意思.在此实现中,要按键查找/搜索/查找值,您必须遍历数组的每个元素,并将该索引处的字符串与您要查找的键进行比较,直到找到它为止(因此您有O(n)阵列性能).您也可以拥有重复的密钥*绝对*不是您想要的.正确的字典/地图实现在密钥上使用散列函数,因此搜索和访问都是O(1)*和*,保证每个密钥只有一个值.在实现有序地图方面,这个答案完全错误. (9认同)
  • @Lahav查找时间是找到任意元素的时间.我相信你在考虑访问时间.在数组的情况下,在最坏情况下找到元素的时间是O(n),假设具有线性搜索的未排序数组.使用排序数组,您可以获得更好的性能,但仍然没有找到在O(1)中找到任何元素的字典/映射. (7认同)

chr*_*nse 30

您可以通过键入类型来订购它们Int.

var myDictionary: [Int: [String: String]]?
Run Code Online (Sandbox Code Playgroud)

要么

var myDictionary: [Int: (String, String)]?
Run Code Online (Sandbox Code Playgroud)

我推荐第一个,因为它是一种更常见的格式(例如JSON).

  • 我最终将创建一个自定义类,但它几乎会做与第一个示例相同的事情(它只是更容易实现)。谢谢你! (2认同)
  • FWIW,`Dictionary`排序行为正式_undefined_.我怀疑他们会改变它,以便"Int"键不会按照你期望的方式进行排序,尽管如此,虽然它现在可能有用,但不能保证它将来会在其他系统上运行. (2认同)
  • 这并不意味着迭代访问它依赖于字典内部如何对其值进行排序。相反,该解决方案依赖于使用 Int 值以已知的排序顺序访问其值,即`let dictionary: [Int: String] = [0: "a", 3: "d", 1: "b", 2: "c"]`, `(0 ..&lt; dictionary.count).map { print(dictionary[$0] }` 仍然会打印 `"a" "b" "c" "d"`。但是`Dictionary ` 内部对其值进行排序,通过将 `Int` 值从 0 迭代到项目计数来访问这些值将始终导致相同的顺序 (2认同)

cof*_*der 24

"如果您需要有序的键值对集合,并且不需要Dictionary提供的快速键查找,请参阅DictionaryLiteral类型以获取替代方案." - https://developer.apple.com/reference/swift/dictionary

  • 这是那些想要创建`JSON`的人的答案,他们正在拉他们的头发,因为Swift`dictionary`不保留顺序.需要更多的赞成...... (3认同)
  • @Suhaib嗯,这是一个文字,所以它的使用仅限于一组预定义的小值.这不像你可以在创建后添加键值. (2认同)
  • @Suhaib,你如何在`JSONSerialization.data(withJSONObject:)`中使用它? (2认同)

bar*_*mes 16

您可以使用KeyValuePairs,来自文档

当您需要键值对的有序集合并且不需要 Dictionary 类型提供的快速键查找时,请使用 KeyValuePairs 实例。

let pairs: KeyValuePairs = ["john": 1,"ben": 2,"bob": 3,"hans": 4]
print(pairs.first!)
Run Code Online (Sandbox Code Playgroud)

//打印(键:“约翰”,值:1)


Dun*_*n C 7

正如Matt所说,词典(和集合)是Swift(和Objective-C)中的无序集合.这是设计的.

如果需要,您可以创建字典键的数组,并将其排序为您想要的任何顺序,然后使用它从字典中获取项目.

NSDictionary有一个方法allKeys,它为您提供数组中字典的所有键.我似乎记得类似于Swift Dictionary对象的东西,但我不确定.我还在学习Swift的细微差别.

编辑:

对于Swift Dictionaries来说 someDictionary.keys


小智 6

如果您的键确认为 Comparable,您可以从未排序的字典中创建一个排序的字典,如下所示

let sortedDictionary = unsortedDictionary.sorted() { $0.key > $1.key }
Run Code Online (Sandbox Code Playgroud)

  • 这不会返回排序的字典。它返回一个排序的 (key, value) 元组数组。 (7认同)