简体   繁体   English

斯威夫特:排序字典

[英]Swift: A sorted dictionary

I'm learning swift and trying to understand dictionaries.我正在快速学习并试图理解字典。 I'm used to PHP, where you might write the following...我已经习惯了 PHP,你可能会在其中写下以下...

$dataPoints = Array("A"=>1,"B"=>2,"C"=>3);
foreach($dataPoints as $value) {
    echo($value);
}

In this example, the values would be output in order - 1, 2, 3在此示例中,值将按顺序输出 - 1, 2, 3

My swift code looks like this...我的快速代码看起来像这样......

var dataPoints: Dictionary<String,Int> = ["A":1,"B":2,"C":3]
for (key, value) in dataPoints {
        print(value)
}

However, the values come out in an unexpected order.但是,这些值的出现顺序出乎意料。 Is there something clean I can do to keep the values in the order they were created, or can a swift dictionary never be sorted?有什么我可以做的干净的事情来保持值的创建顺序,或者永远不会对快速字典进行排序?

As has already been answered, the point of a dictionary is that it is not sorted.正如已经回答的那样,字典的重点是它没有排序。 There are three types of collections in Swift (and Objective-C)在 Swift(和 Objective-C)中有三种类型的集合

An array is an ordered list of items.数组是项目的有序列表。 Use this when the order of the items is important.当项目的顺序很重要时使用它。

A dictionary is an unordered collection of keys and values.字典是键和值的无序集合。 Use this when you want to efficiently retrieve a value based on a key.当您想根据键有效地检索值时,请使用此选项。

A set is a bag of unordered, unique items.一套是一袋无序的、独特的物品。 Use this when you want to have a collection of unique items in no particular order.当您想拥有一组没有特定顺序的独特项目时,请使用此选项。

For your case it seems that the ordering is what is important to you, but you want to store some kind of pair of values.对于您的情况,排序似乎对您很重要,但您想存储某种值对。 Perhaps what you should be looking at is using an array of tuples:也许您应该关注的是使用一组元组:

something like this, maybe像这样的东西,也许

let dataPoints = [("A", 1), ("B", 2), ("C", 3)]

for (letter, number) in dataPoints {
    print("\(letter), \(number)")
}

which outputs哪个输出

A, 1
B, 2
C, 3

Alternatively或者

If you don't know about the order of the items before their creation, but there is a natural ordering based on the keys, you could do something like this:如果您在创建之前不知道项目的顺序,但有基于键的自然排序,您可以执行以下操作:

let dict = [
    "A" : 1,
    "B" : 2,
    "C" : 3
]

for key in dict.keys.sort() {
    guard let value = dict[key] else { break }
    print("\(key), \(value)")
}

In this case you get an array of keys with their default sort order (you can use a different sort function if you have other requirements) and output the key values based on that sorted order.在这种情况下,您将获得具有默认排序顺序的键数组(如果您有其他要求,可以使用不同的排序函数)并根据该排序顺序输出键值。

From Apple docs :来自苹果文档

Unlike items in an array, items in a dictionary do not have a specified order.与数组中的项目不同,字典中的项目没有指定的顺序。

So, no, Swift dictionary are never "sorted".所以,不,Swift 字典永远不会“排序”。 However, a quick Google search for "Swift ordered dictionary "will yield several implementation which may serve your needs:但是,在 Google 上快速搜索“Swift 有序字典”将产生几种可能满足您需求的实现:

For example:例如:

https://github.com/lukaskubanek/OrderedDictionary https://github.com/lukaskubanek/OrderedDictionary

https://github.com/Marxon13/M13DataStructures/blob/master/Classes/OrderedDictionary.swift https://github.com/Marxon13/M13DataStructures/blob/master/Classes/OrderedDictionary.swift

Cocoapods could also help: Cocoapods 还可以帮助:

https://cocoapods.org/?q=ordered%20dict https://cocoapods.org/?q=ordered%20dict

您现在可以使用官方 Apple Collections 库中的 OrderedDictionary: https : //github.com/apple/swift-collections

Just in case this is useful, based on the responses here and because I was receiving data from a JSON source, I decided the best approach was for me to convert my dictionary into a sorted array of tuples.以防万一这是有用的,基于这里的响应,并且因为我从 JSON 源接收数据,我决定最好的方法是将我的字典转换为一个排序的元组数组。 I created the following function for this:我为此创建了以下函数:

func dictionary_to_sorted_array(dict:Dictionary<String,Int>) ->Array<(key:String,value:Int)> {
    var tuples: Array<(key:String,value:Int)> = Array()
    let sortedKeys = (dict as NSDictionary).keysSortedByValueUsingSelector("compare:")
    for key in sortedKeys {
        tuples.append((key:key as! String,value:dict[key as! String]!))
    }
    return tuples
}

So then, I could use the following code:那么,我可以使用以下代码:

var dataPoints: Dictionary<String,Int> = ["A":1,"B":2,"C":3]
dataPointsArray(dictionary_to_sorted_array(dataPoints))
for dataPoint in dataPointsArray {
    print(dataPoint.value)
}

I'm very much a beginner with swift, so if anybody has a quicker way of doing this, that would be great!我是 swift 的初学者,所以如果有人有更快的方法来做到这一点,那就太好了!

From Swift 4, you can use sorted(by:) to return a sorted array of the dictionary's elements (tuples).从 Swift 4 开始,您可以使用sorted(by:)返回字典元素(元组)的排序数组。 So the code from your question becomes:因此,您问题中的代码变为:

var dataPoints = ["A":1,"B":2,"C":3]

var sortedDataPoints = dataPoints.sorted(by: { $0.value < $1.value })
// [(key: "A", value: 1), (key: "B", value: 2), (key: "C", value: 3)]

for (_, value) in sortedDataPoints {
    print(value)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM