Как объединить два массива в словарь?

у меня есть 2 массива:

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

я добавил их с данными. Теперь для удобства использования моя цель-объединить их все в словарь со следующей структурой

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

Я просматривал сеть и не мог найти жизнеспособного решения для этого.

любые идеи очень ценятся.

спасибо!

6 ответов


это звучит как работа для .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]
        }
    }
}

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


немного другой метод, который не требует, чтобы массивы были одинаковой длины, потому что zip функция будет безопасно обрабатывать это.

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

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

начиная с 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 })

документы:


Если вы хотите быть более безопасным и убедиться, что вы выбираете меньший счетчик массивов каждый раз (так что вы не потенциально сбой, если второй массив меньше первого), то сделайте что-то вроде:

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

это общее решение

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)

вот расширение, которое объединяет некоторые из предыдущих ответов и принимает все последовательности, а не только массивы.

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