Swift equivalent to “

Is there an equivalent for Swift’s native Dictionary to [NSDictionary initWithObjects: forKeys:]?

Say I have two arrays with keys and values and want to put them in a dictionary. In Objective-C I’d do it like this:

  • Is it possible to discover Gimbal beacons with standard iOS libraries
  • Downloading normal image Vs retina device image (2x)
  • Search as you type Swift
  • iOS9 - This application is modifying the autolayout engine from a background thread — where?
  • Forcing iPhone Microphone as Audio Input
  • How To Get Selected Value From UIPickerView
  • NSArray *keys = @[@"one", @"two", @"three"];
    NSArray *values = @[@1, @2, @3];
    NSDictionary *dict = [[NSDictionary alloc] initWithObjects: values forKeys: keys];
    

    Of course I can iterate with a counter through both arrays, use a var dict: [String:Int] and add stuff step by step. But that doesn’t seem to be a good solution. Using zip and enumerate are probably better ways of iterating over both at the same time. However this approach means having a mutable dictionary, not an immutable one.

    let keys = ["one", "two", "three"]
    let values = [1, 2, 3]
    // ???
    let dict: [String:Int] = ["one":1, "two":2, "three":3] // expected result
    

    4 Solutions Collect From Internet About “Swift equivalent to “”

    A one-liner, using zip and reduce:

    let dict = zip(keys, values).reduce([String:Int]()){ var d = $0; d[$1.0] = $1.1; return d }
    

    You can shorten the reduce expression by defining the + operator for a Dictionary and a tuple:

    func +<K,V>(lhs: [K:V], rhs: (K, V)) -> [K:V] {
        var result = lhs
        result[rhs.0] = rhs.1
        return result
    }
    
    let dict = zip(keys, values).reduce([String:Int](), combine: +)
    

    You can simply use the Swift equivalent of initWithObjects:forKeys:

    let keys = ["one", "two", "three"]
    let values = [1, 2, 3]
    var dict = NSDictionary.init(objects: values, forKeys: keys)
    

    Working pure Swift solution with structs. Use zip to iterate through your two arrays as a tuple, and then create a dictionary for each key, value in the tuple.

    struct SomeStruct {
        var someVal: Int?
    }
    
    var keys = [String]()
    var values = [SomeStruct]()
    
    for index in 0...5 {
        keys.append(String(index))
        values.append(SomeStruct(someVal: index))
    }
    
    var dict = [String : Any]()
    
    for (key, value) in zip(keys, values) {
        dict[key] = value
    }
    
    print(dict) // "["4": SomeStruct(someVal: Optional(4)), "2": SomeStruct(someVal: Optional(2)), "1": SomeStruct(someVal: Optional(1)), "5": SomeStruct(someVal: Optional(5)), "0": SomeStruct(someVal: Optional(0)), "3": SomeStruct(someVal: Optional(3))]"
    

    You could also use forEach on zip:

    var dict = [String : Any]()
    zip(keys, values).forEach { dict[$0.0] = $0.1 }
    print(dict) // "["4": SomeStruct(someVal: Optional(4)), "2": SomeStruct(someVal: Optional(2)), "1": SomeStruct(someVal: Optional(1)), "5": SomeStruct(someVal: Optional(5)), "0": SomeStruct(someVal: Optional(0)), "3": SomeStruct(someVal: Optional(3))]\n"
    
    let keys = ["one", "two", "three"]
    let values = [1, 2, 3]
    
    func createDict<K:Hashable,V>(keys: [K], values:[V])->[K:V] {
    
        var dict: [K:V] = [:]
    
        // add validity checks here by yourself !
        // and return early, or throw an error ...
    
        keys.enumerate().forEach { (index,element) -> () in
            dict[element] = values[index]
        }
        return dict
    }
    
    let dict = createDict(keys, values: values)
    // ["one": 1, "three": 3, "two": 2]
    
    let dict2:[Int:Any] = createDict([1,2,3,4,5], values: [true,"two",3.4,5,[1,2,3]])
    // [5: [1, 2, 3], 2: "two", 3: 3.4, 1: true, 4: 5]
    

    what is the difference if it is compared to zip solution?
    hard to say … for me the zip type annotation is the biggest issue

    let a:Zip2Sequence<[Int],[Any]> = zip([1,2,3,4,5], [true,"two",3.4,5,[1,2,3]])
    var d:[Int:Any] = [:]
    a.forEach { (key, value) -> () in
        d[key] = value
    }
    print(d)
    // [5: [1, 2, 3], 2: "two", 3: 3.4, 1: true, 4: 5]
    

    but enumerate solution is also a little bit quicker