已在Swift中订购地图



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)

有没有任何内置的方法可以创建一个有序的key : value映射,该映射的排序方式与数组相同,或者我必须创建自己的类?

如果可能的话,我会尽量避免创建自己的类,因为Swift包含的任何内容都可能更高效。

您可以通过具有类型为Int的键来订购它们。

var myDictionary: [Int: [String: String]]?

var myDictionary: [Int: (String, String)]?

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

只需使用元组数组即可。按你喜欢的排序。全部"内置"。

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

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

您可以使用KeyValuePairs,来自文档:

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

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

//打印(键:"john",值:1)

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

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

正如Matt所说,字典(和集合)在Swift(和Objective-C)中是无序的集合。这是经过设计的。

如果你愿意,你可以创建一个字典键的数组,并将其按你想要的任何顺序排序,然后用它从字典中提取项目。

NSDictionary有一个方法allKeys,它在一个数组中为您提供字典的所有键。我似乎记得Swift Dictionary对象的类似内容,但我不确定。我仍在学习斯威夫特的细微差别。

编辑:

对于Swift Dictionaries,它是someDictionary.keys

您可以使用原始Swift Repo的官方OrderedDictionary

已订购的集合当前包含:

  • 有序字典(您正在查找)
  • 有序集

他们说它很快就会合并到Swift中(在WWDC21中)

Swift不包含任何内置的有序字典功能,而且据我所知,Swift 2也没有

然后你将创造你自己的。您可以查看这些教程以获得帮助:

  • http://timekl.com/blog/2014/06/02/learning-swift-ordered-dictionaries/
  • http://www.raywenderlich.com/82572/swift-generics-tutorial

我知道我是聚会的18人,但你调查过NSMutableOrderedSet吗?

https://developer.apple.com/reference/foundation/nsorderedset

当在测试对象是否包含在集合中是一个考虑因素--测试数组比测试集合的成员身份要慢。

    var orderedDictionary = [(key:String, value:String)]()

正如其他人所说,没有对这种类型的结构的内置支持。他们可能会在某个时候向标准库添加一个实现,但鉴于在大多数应用程序中是最佳解决方案的情况相对较少,所以我不会屏住呼吸。

一个替代方案是OrderedDictionary项目。由于它遵循BidirectionalCollection,您可以获得大多数与其他Collection类型可能习惯使用的API相同的API,而且(目前)它似乎得到了相当好的维护。

以下是我所做的,非常简单:

let array = [
    ["foo": "bar"],
    ["foo": "bar"],
    ["foo": "bar"],
    ["foo": "bar"],
    ["foo": "bar"],
    ["foo": "bar"]
]
// usage
for item in array {
    let key = item.keys.first!
    let value = item.values.first!
    print(key, value)
}

键不是唯一的,因为这不是Dictionary而是Array,但您可以使用数组键。

使用Dictionary.enumerated()

示例:

let dict = [
    "foo": 1,
    "bar": 2,
    "baz": 3,
    "hoge": 4,
    "qux": 5
]

for (offset: offset, element: (key: key, value: value)) in dict.enumerated() {
    print("(offset): '(key)':(value)")
}
// Prints "0: 'bar':2"
// Prints "1: 'hoge':4"
// Prints "2: 'qux':5"
// Prints "3: 'baz':3"
// Prints "4: 'foo':1"

最新更新