【问题标题】:Swift: A sorted dictionarySwift:排序字典
【发布时间】:2016-03-03 23:50:36
【问题描述】:

我正在快速学习并尝试理解字典。我习惯了PHP,你可能会在其中编写以下内容...

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

在本例中,值将按顺序输出 - 1、2、3

我的 swift 代码如下所示...

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

但是,这些值以意外的顺序出现。有没有什么我可以做的干净的事情来保持值的创建顺序,或者不能对快速字典进行排序?

【问题讨论】:

标签: swift dictionary


【解决方案1】:

正如已经回答的那样,字典的重点是它没有排序。在 Swift(和 Objective-C)中有三种类型的集合

数组是项目的有序列表。当项目的顺序很重要时使用它。

字典是键和值的无序集合。如果您想根据键有效地检索值,请使用此选项。

一套是一袋无序的、独特的物品。当您希望拥有一组不按特定顺序的独特项目时,请使用此选项。

对于您的情况,排序似乎对您很重要,但您想存储某种值对。也许你应该看的是使用元组数组:

可能是这样的

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

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

哪个输出

A, 1
B, 2
C, 3

或者

如果您在创建项目之前不知道项目的顺序,但存在基于键的自然排序,您可以执行以下操作:

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

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

在这种情况下,您将获得一个具有默认排序顺序的键数组(如果您有其他要求,可以使用不同的排序函数)并根据该排序顺序输出键值。

【讨论】:

    【解决方案2】:

    来自Apple docs

    与数组中的项目不同,字典中的项目没有指定的顺序。

    所以,不,Swift 字典永远不会“排序”。但是,在 Google 上快速搜索“Swift 有序字典”将产生几个可能满足您需求的实现:

    例如:

    https://github.com/lukaskubanek/OrderedDictionary

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

    Cocoapods 也有帮助:

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

    【讨论】:

    • 感谢 Guillaume,这非常有用。如果您不介意,我还有几个问题: 1 - 如果字典是从 JSON 字符串创建的怎么办 - 您永远不知道原始顺序吗? 2 - 是否有一个好的键/值数据类型可以使用,以便我可以创建它们的有序数组?
    • 1- 不,这不会改变任何事情,字典永远不会保留顺序。请注意,JSON“字典”(stackoverflow.com/questions/7198412/…)也是这种情况,它们也没有订单。 2- 根据您的需要,您可以将数据存储到结构或类的数组中,这将保持顺序并具有强类型。
    【解决方案3】:

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

    【讨论】:

    【解决方案4】:

    以防万一这很有用,根据这里的响应并且因为我从 JSON 源接收数据,我决定最好的方法是将我的字典转换为一个排序的元组数组。我为此创建了以下函数:

    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
    }
    

    那么,我可以使用以下代码:

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

    我是 swift 的初学者,所以如果有人有更快的方法,那就太好了!

    【讨论】:

      【解决方案5】:

      从 Swift 4 开始,您可以使用 sorted(by:) 返回字典元素(元组)的排序数组。因此,您问题中的代码变为:

      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)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-22
        • 2016-11-19
        • 2016-09-14
        • 2016-05-14
        • 1970-01-01
        • 2015-07-15
        相关资源
        最近更新 更多