Home > Software engineering >  Handling of a Dictionary Element in the context of "Array" notation
Handling of a Dictionary Element in the context of "Array" notation

Time:06-29

Struggling to achieve 2) below.

In the examples below, T is a concrete type. T could be String but the examples would then look even stranger.

  1. Works:

     var v = [         // v is a Dictionary with two Dictionary<String, T>.Element's
         "x": T("x"),  // Unfortunate since "x" has to be repeated    
         "y": T("y") 
     ]
    
  2. Desired syntax, intended to do the same as 1). Does not work:

     var v = [        
         { let s = "x";             // Attempting to use a closure to "inline" the local variable s
           return (s: T(name: s))   // Using a tuple to return the Dictionary<String, T>.Element
         }(),
         { let s = "y";   
           return (s: T(name: s))
         }()
     ]
    

Xcode error for 2): Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional

  1. Trying to fix 2) with explicit types. Does not work.

     var v : Dictionary<String, T>.Element = [        
         { let s = "x";             
           return Dictionary<String, T>.Element(s: T(name: s))
         }(),
         { let s = "y";             
           return Dictionary<String, T>.Element(s: T(name: s))
         }()
     ]
    

Xcode error for 3): Dictionary of type 'Dictionary<String, T>' cannot be initialized with array literal

This "MWE" example admittedly looks weird, but I am trying to understand how, in general, it may be possible to use a Dictionary Element (Key and Value together, as a hole) as if it were (informally speaking) an element of an Array. My understanding may be totally flawed. However, the following is an example of something that does work:

  1. Different from above, but works:

    var v = [ Dictionary<String, T>.Element(key: "x", value: T("x")) ]
    

Edit.

  1. This also works:

     var v = Dictionary<String, T>(uniqueKeysWithValues:
         [ { let s = "x"; return Dictionary<String, T>.Element(s, T("x")) }() ]
     )
    

So Im concluding for now that the "logic" behind that naive array notation does not work, is that you have to be explicit about unique keys... why you need this explicitness, however, I do not understand.

CodePudding user response:

If you have an array of keys and you want to create a dictionary out of it by mapping each key to another type, I'd suggest this way:

let keys = ["x", "y", "z"]
let dict = Dictionary(
    uniqueKeysWithValues: keys.map { key in (key, T(key)) }
)

CodePudding user response:

I am still not sure exactly what you want but I thought I add this solution to see if it is correct or at least something to discuss further

struct T {
    let name: String
}

extension Dictionary where Key == String, Value == T {
    init(values: Key...) {
        self = values.reduce(into: [:]) { $0[$1] = T(name: $1) }
    }
}

var dict = Dictionary(values: "x", "y")
  • Related