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

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

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

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

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

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

Любые идеи приветствуются.

Спасибо!

Ответ 1

Используйте 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)

Ответ 2

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

Документация:

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

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