5 Replies
      Latest reply on Aug 11, 2018 5:40 PM by OOPer
      dhoerl Level 1 Level 1 (0 points)

        I'm stumped so posting here.

         

        I have some vendor code that supplies a dictionary: [String: [String: Obj]], where Obj is a ObjC object with a "tag" and "value", both are strings. I'd love to use a higher level Swift library method to do the following:

         

                var dict: [String: String] = [:]
                input.forEach() { (key, obj) in
                    dict[obj.tag] = obj.value
                }

         

        Can I use map for this? [I tried to get it but no luck.]

        • Re: How to use map/flatmap for conversion?
          OOPer Level 7 Level 7 (4,315 points)

          It's not clear what is the type of `input` in your code. If it is ` [String: [String: Obj]]`, your `forEach` does not work.

           

          Please show the type of `input` and some sample data with expected result.

            • Re: How to use map/flatmap for conversion?
              dhoerl Level 1 Level 1 (0 points)

              Sigh. I had THOUGHT that was the format originally - its actually [String: Obj] - sorry for the confusion. The Obj also contains the tag in this array, which is just so odd - its total duplication.

                • Re: How to use map/flatmap for conversion?
                  OOPer Level 7 Level 7 (4,315 points)

                  Then your data, logically, looks like this?

                   

                  let input1: [String: Obj] = [
                      "tag1": Obj(tag: "tag1", value: "value1"),
                      "tag2": Obj(tag: "tag2", value: "value2"),
                      "tag3": Obj(tag: "tag3", value: "value3"),
                  ]
                  
                    • Re: How to use map/flatmap for conversion?
                      dhoerl Level 1 Level 1 (0 points)

                      YES!

                        • Re: How to use map/flatmap for conversion?
                          OOPer Level 7 Level 7 (4,315 points)

                          Then you can use `mapValues` instead of `map` or `flatMap`.

                          let input1: [String: Obj] = [
                              "tag1": Obj(tag: "tag1", value: "value1"),
                              "tag2": Obj(tag: "tag2", value: "value2"),
                              "tag3": Obj(tag: "tag3", value: "value3"),
                          ]
                          
                          let dict1 = input1.mapValues {$0.value}
                          print(dict1)

                          Output:

                          ["tag3": "value3", "tag1": "value1", "tag2": "value2"]

                           

                          But this is equivalent to something like this:

                              var dict1: [String: String] = [:]
                              input1.forEach() { (key, obj) in
                                  dict1[key] = obj.value //Not `dict[obj.tag]`
                              }
                              print(dict1)
                          
                          

                           

                          If key and tag do not make duplicate and you want to get exactly the same result as in your code of the opening post,

                          you may need to combine some Dictionary initializer with `map`. (Usual `map` creates an Array, not a Dictionary.)

                           

                          Anyway this is worth reading:

                          Dictionary and Set Improvements in Swift 4.0