在Swift字典中反转键的值,收集重复值

时间:2018-03-03 19:33:43

标签: swift dictionary

我有以下字典:

let dict = ["key1": "v1", "key2": "v1", "key3": "v2"]

我想交换键的值,以便结果为:

result = ["v1": ["key1", "key2"], "v2": ["key3"]]

如何在不使用for循环(即更优雅)的情况下执行此操作?

3 个答案:

答案 0 :(得分:4)

您可以在Swift 4中使用分组初始化程序:

let dict = ["key1": "v1", "key2": "v1", "key3": "v2"]
let result = Dictionary(grouping: dict.keys.sorted(), by: { dict[$0]! })

两个注释:

  1. 如果结果数组中的键顺序不重要,则可以删除.sorted()
  2. 在这种情况下,强制解包是安全的,因为我们将现有字典键作为$0参数
  3. 获取

答案 1 :(得分:2)

在Swift 4中,Dictionaryinit(_:uniquingKeysWith:)初始化程序,应该在这里很好用。

let d = [1 : "one", 2 : "two", 3 : "three", 30: "three"]
let e = Dictionary(d.map({ ($1, [$0]) }), uniquingKeysWith: {
    (old, new) in old + new
})

如果原始字典中没有需要合并的重复值,则更简单(使用another new initializer):

let d = [1 : "one", 2 : "two", 3 : "three"]
let e = Dictionary(uniqueKeysWithValues: d.map({ ($1, $0) }))

答案 2 :(得分:0)

这是常用的按键对键值对进行分组的功能的特殊应用。

public extension Dictionary {
  /// Group key-value pairs by their keys.
  ///
  /// - Parameter pairs: Either `Swift.KeyValuePairs<Key, Self.Value.Element>`
  ///   or a `Sequence` with the same element type as that.
  /// - Returns: `[ KeyValuePairs.Key: [KeyValuePairs.Value] ]`
  init<Value, KeyValuePairs: Sequence>(grouping pairs: KeyValuePairs)
  where
    KeyValuePairs.Element == (key: Key, value: Value),
    Self.Value == [Value]
  {
    self =
      Dictionary<Key, [KeyValuePairs.Element]>(grouping: pairs, by: \.key)
      .mapValues { $0.map(\.value) }
  }

  /// Group key-value pairs by their keys.
  ///
  /// - Parameter pairs: Like `Swift.KeyValuePairs<Key, Self.Value.Element>`,
  ///   but with unlabeled elements.
  /// - Returns: `[ KeyValuePairs.Key: [KeyValuePairs.Value] ]`
  init<Value, KeyValuePairs: Sequence>(grouping pairs: KeyValuePairs)
  where
    KeyValuePairs.Element == (Key, Value),
    Self.Value == [Value]
  {
    self.init( grouping: pairs.map { (key: $0, value: $1) } )
  }
}

有了它,只需翻转每个键值对并前往城镇即可。

Dictionary( grouping: dict.map { ($0.value, $0.key) } )
相关问题