【问题标题】:How can I merge two arrays into a dictionary?如何将两个数组合并到字典中?
【发布时间】:2015-11-15 10:29:10
【问题描述】:

我有 2 个数组:

    var identic = [String]()
    var linef = [String]()

我已经为它们附加了数据。现在出于可用性目的,我的目标是将它们全部组合成具有以下结构的字典

FullStack = ["identic 1st value":"linef first value", "identic 2nd value":"linef 2nd value"]

我一直在网上浏览,找不到可行的解决方案。

非常感谢任何想法。

谢谢!

【问题讨论】:

  • 一切都是关于 zip,它会为您完成这些

标签: ios arrays swift dictionary


【解决方案1】:

从 Xcode 9.0 开始,您可以这样做:

var identic = [String]()
var linef = [String]()

// Add data...

let fullStack = Dictionary(uniqueKeysWithValues: zip(identic, linef))

如果您的密钥不能保证是唯一的,请改用它:

let fullStack =
    Dictionary(zip(identic, linef), uniquingKeysWith: { (first, _) in first })

let fullStack =
    Dictionary(zip(identic, linef), uniquingKeysWith: { (_, last) in last })

文档:

【讨论】:

【解决方案2】:

使用enumerated():

var arrayOne: [String] = []
var arrayTwo: [String] = []

var dictionary: [String: String] = [:]

for (index, element) in arrayOne.enumerated() {
    dictionary[element] = arrayTwo[index]
}

pro 方法是使用扩展:

extension Dictionary {
    public init(keys: [Key], values: [Value]) {
        precondition(keys.count == values.count)

        self.init()

        for (index, key) in keys.enumerate() {
            self[key] = values[index]
        }
    }
}

编辑: enumerate()enumerated() (Swift 3 → Swift 4)

【讨论】:

  • 我将此扩展添加到我的项目中,但是当我尝试使用它初始化字典时,我没有看到初始化程序。你能添加示例用法吗?
  • 从某种意义上说,这个答案实际上并不正确——您只需使用 zip 来做到这一点。
【解决方案3】:

这是一个扩展,它结合了之前的一些答案并接受所有序列,而不仅仅是数组。

public extension Dictionary {
    init<K: Sequence, V: Sequence>(keys: K, values: V) where K.Element == Key, V.Element == Value, K.Element: Hashable {
        self.init()
        for (key, value) in zip(keys, values) {
            self[key] = value
        }
    }
}

该扩展不需要序列长度相同。如果你想要,这里有一个带有断言的扩展。

public extension Dictionary {
    init<K: Sequence, V: Sequence>(keys: K, values: V) where K.Element == Key, V.Element == Value, K.Element: Hashable {
        self.init()
        var keyIterator = keys.makeIterator()
        for value in values {
            let key = keyIterator.next()
            assert(key != nil, "The value sequence was longer.")
            self[key!] = value
        }
        assert(keyIterator.next() == nil, "The key sequence was longer.")
    }
}

【讨论】:

    【解决方案4】:

    一种稍微不同的方法,它不需要数组的长度相同,因为zip 函数会安全地处理它。

    extension Dictionary {
        init(keys: [Key], values: [Value]) {
            self.init()
    
            for (key, value) in zip(keys, values) {
                self[key] = value
            }
        }
    }
    

    【讨论】:

    • 当数组长度不同时,输出是什么?
    • 它只将内容压缩到最短数组的长度。
    【解决方案5】:

    如果您想更安全并确保每次都选择较小的数组计数(这样如果第二个数组小于第一个数组,您就不会崩溃),那么请执行以下操作:

    var identic = ["A", "B", "C", "D"]
    var linef = ["1", "2", "3"]
    
    var Fullstack = [String: String]()
    for i in 0..<min(linef.count, identic.count) {
        Fullstack[identic[i]] = linef[i]
    }
    
    print(Fullstack) // "[A: 1, B: 2, C: 3]"
    

    【讨论】:

      【解决方案6】:

      这是一个通用的解决方案

      func dictionaryFromKeysAndValues<K : Hashable, V>(keys:[K], values:[V]) -> Dictionary<K, V>
      {
        assert((count(keys) == count(values)), "number of elements odd")
        var result = Dictionary<K, V>()
        for i in 0..<count(keys) {
          result[keys[i]] = values[i]
        }
        return result
      }
      
      var identic = ["identic 1st value", "identic 2nd value", "identic 3rd value"]
      var linef = ["linef 1st value", "linef 2nd value", "linef 3rd value"]
      
      let mergedDictionary = dictionaryFromKeysAndValues(identic, linef)
      

      【讨论】:

      • 不一样,我没有使用 enumerate() 并且我的是一个不限于字符串的通用解决方案。
      • 我的也是通用解决方案。
      猜你喜欢
      • 2020-05-30
      • 1970-01-01
      • 2019-05-16
      • 2012-09-20
      • 2019-11-11
      • 2018-05-13
      • 2018-04-22
      • 2021-04-10
      • 2021-12-07
      相关资源
      最近更新 更多