45

From a source I cannot influence I am given data in a map, which arrives as map[interface {}]interface {}.

I need to process the contained data, preferably as map[string]string (the data within is perfectly suitable for that).

I need to generate a list of the keys from the data as well, as those are not known beforehand.

Most similar questions I could find on the web say more or less, that this is impossible, but if my map is m, fmt.Println(m) shows the data is there, readable as map[k0:v0 K1:v1 k2:v2 ... ].

How can I do what fmt.Println is able to do?

Alex K
  • 8,269
  • 9
  • 39
  • 57
user3160501
  • 553
  • 1
  • 4
  • 5
  • 1
    of course the data is there, you just have to iterate through the map. There's no way to directly convert those structures. – JimB Nov 17 '14 at 15:53
  • 1
    possible duplicate of [Type converting slices of interfaces in go](http://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go) – JimB Nov 17 '14 at 16:01
  • i guess i have to reask. The map i get does refuse to iterate, while the answer of @Swoogan does work perfectly. – user3160501 Nov 17 '14 at 16:45

3 Answers3

30

A secure way to process unknown interfaces, just use fmt.Sprintf()

https://play.golang.org/p/gOiyD4KpQGz

package main

import (
    "fmt"
)

func main() {

    mapInterface := make(map[interface{}]interface{})   
    mapString := make(map[string]string)

    mapInterface["k1"] = 1
    mapInterface[3] = "hello"
    mapInterface["world"] = 1.05

    for key, value := range mapInterface {
        strKey := fmt.Sprintf("%v", key)
        strValue := fmt.Sprintf("%v", value)

        mapString[strKey] = strValue
    }

    fmt.Printf("%#v", mapString)
}
wakumaku
  • 616
  • 5
  • 5
18

Perhaps I misunderstand the question, but would this work?

m := make(map[interface{}]interface{})
m["foo"] = "bar"

m2 := make(map[string]string)   

for key, value := range m {        
    switch key := key.(type) {
    case string:
        switch value := value.(type) {
        case string:
            m2[key] = value
        }
    }
}
Swoogan
  • 5,298
  • 5
  • 35
  • 47
  • 6
    FYI, you can assign in a switch statement, so you don't have to don't have to so the type assertion: http://play.golang.org/p/-ZeUXTKu9a – JimB Nov 17 '14 at 15:58
  • Right, must have missed that in my rush to answer. Thanks! – Swoogan Nov 17 '14 at 15:59
  • Thank you! This is what i tried initially, but failed. Your example does work, while "my" map refuses to range due to type interface {}. Both are reported as "map[interface {}]interface {}" by reflect.TypeOf but behave differently....???? – user3160501 Nov 17 '14 at 16:28
  • @user3160501: You're probably further obscuring the issue by passing `map[interface{}]interface{}` as an `interface{}`. Sounds like you need another type assertion in there, but you need to show an example if you want help. – JimB Nov 17 '14 at 16:36
  • @JimB: sounds like you are pointing in a well helpful direction, although i cannot yet either find where in my code this does happen, nor how i can wrap up a good example. But i will try the latter! – user3160501 Nov 17 '14 at 20:30
0

// data is map[string]interface{}

form := make(map[string]string)

for k, v := range data {
    form[k] = v.(string)
}
vinnitu
  • 4,234
  • 10
  • 41
  • 59