I have 2 arrays:
var identic = [String]()
var linef = [String]()
I\'ve appended them with data. Now for usability purposes my goal
Starting with Xcode 9.0, you can simply do:
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:
https://developer.apple.com/documentation/swift/dictionary/3127165-init
https://developer.apple.com/documentation/swift/dictionary/3127161-init
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)
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]"
Use enumerated()
:
var arrayOne: [String] = []
var arrayTwo: [String] = []
var dictionary: [String: String] = [:]
for (index, element) in arrayOne.enumerated() {
dictionary[element] = arrayTwo[index]
}
The pro approach would be to 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)
A slightly different method, which doesn't require the arrays to be of the same length, because the zip
function will safely handle that.
extension Dictionary {
init(keys: [Key], values: [Value]) {
self.init()
for (key, value) in zip(keys, values) {
self[key] = value
}
}
}
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.")
}
}