如何将两个数组合并到字典中?

时间:2022-09-06 15:36:07

I have 2 arrays:

我有2个数组:

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

I've appended them with data. Now for usability purposes my goal is to combine them all into a dictionary with the following structure

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

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

I've been browsing around the net and couldnt find a viable solution to this.

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

Any ideas are greatly appreciated.

任何想法都非常感谢。

Thank you!

谢谢!

6 个解决方案

#1


22  

This sounds like a job for .enumerated()!

这听起来像.enumerated()的工作!

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

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

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

However, if you want the pro approach, use an extension:

但是,如果您想要专业方法,请使用扩展名:

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

Edit: enumerate()enumerated() (Swift 3 → Swift 4)

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

#2


18  

A slightly different method, which doesn't require the arrays to be of the same length, because the zip function will safely handle that.

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

extension Dictionary {
    init(keys: [Key], values: [Value]) {
        self.init()

        for (key, value) in zip(keys, values) {
            self[key] = value
        }
    }
}

#3


11  

Starting with Xcode 9.0, you can simply do:

从Xcode 9.0开始,您可以简单地执行以下操作:

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

// Add data...

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

If your keys are not guaranteed to be unique, use this instead:

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

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

or

要么

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

Documentation:

文档:

#4


6  

If you'd like to be safer and ensure you're picking the smaller array count each time (so that you're not potentially crashing if the second array is smaller than the first), then do something like:

如果您想更安全并确保每次都选择较小的数组(如果第二个数组小于第一个数组,则不会发生崩溃),然后执行以下操作:

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]"

#5


2  

This is a generic solution

这是一个通用的解决方案

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)

#6


0  

Here is a extension that combines some of the previous answers and accepts all Sequences, not only Arrays.

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

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

That extension doesn't require the sequences to be the same lengths. If you want that, here is an extension with assertions.

该扩展不要求序列长度相同。如果你想要,那么这是一个带断言的扩展。

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

#1


22  

This sounds like a job for .enumerated()!

这听起来像.enumerated()的工作!

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

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

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

However, if you want the pro approach, use an extension:

但是,如果您想要专业方法,请使用扩展名:

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

Edit: enumerate()enumerated() (Swift 3 → Swift 4)

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

#2


18  

A slightly different method, which doesn't require the arrays to be of the same length, because the zip function will safely handle that.

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

extension Dictionary {
    init(keys: [Key], values: [Value]) {
        self.init()

        for (key, value) in zip(keys, values) {
            self[key] = value
        }
    }
}

#3


11  

Starting with Xcode 9.0, you can simply do:

从Xcode 9.0开始,您可以简单地执行以下操作:

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

// Add data...

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

If your keys are not guaranteed to be unique, use this instead:

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

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

or

要么

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

Documentation:

文档:

#4


6  

If you'd like to be safer and ensure you're picking the smaller array count each time (so that you're not potentially crashing if the second array is smaller than the first), then do something like:

如果您想更安全并确保每次都选择较小的数组(如果第二个数组小于第一个数组,则不会发生崩溃),然后执行以下操作:

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]"

#5


2  

This is a generic solution

这是一个通用的解决方案

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)

#6


0  

Here is a extension that combines some of the previous answers and accepts all Sequences, not only Arrays.

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

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

That extension doesn't require the sequences to be the same lengths. If you want that, here is an extension with assertions.

该扩展不要求序列长度相同。如果你想要,那么这是一个带断言的扩展。

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