Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a map[string]interface{} to string

Tags:

yaml

go

I'm trying to get the path to value from a json file:

for example :

x: 4
z:
  y: 6
  t: 8
a:
  b:
    p: 0
m:
  c : 4 

the output that i want is :

x=4, z.y=6, z.t=8, a.b.p=0, m.c=4

i wrote a functions below :

func parsecustom(aMap map[string]interface{}) (string, string) {

    var sol string
    var k string
    for key, val := range aMap {
        switch concreteVal := val.(type) {
        case map[string]interface{}:
            x, _ := parseMap(val.(map[string]interface{}))
            sol = key + "." + x
            k += sol + ","
        case string:
            sol = key + "=" + concreteVal + " "
            k += sol + ","
        case float64:
            sol = key + "=" + strconv.FormatFloat(concreteVal, 'f', -1, 64) + " "
            k+= sol + ","
        default:
            k = " "

        }
    }

return sol, TrimSuffix(k, ",")
}

but it didn't take into account this case :

z:
  y: 6
  t: 8

it override, it print only z.t=8 and ignore z.y=6

Any hints please how to solve this problem

like image 672
MelDev Avatar asked Sep 26 '26 11:09

MelDev


1 Answers

To address the problem that child values should bearing parents' name, I think when recursing, there needs to be a prefix parameter. And instead of asking the parents to insert those prefix into the string, it would feel more normal to let the children write the prefix just as they are going to write their own parsed results. So I changed your code:

func parseMap(aMap map[string]interface{}, prefix string, b *strings.Builder) {
    var sol string
    for key, val := range aMap {
        switch concreteVal := val.(type) {
        case map[string]interface{}:
            parseMap(concreteVal,prefix+key+".",b)
        case string:
            sol = key + "=" + concreteVal + " "
            b.WriteString(prefix)
            b.WriteString(sol)
            b.WriteRune(',')
        case float64:
            sol = key + "=" + strconv.FormatFloat(concreteVal, 'f', -1, 64) + " "
            b.WriteString(prefix)
            b.WriteString(sol)
            b.WriteRune(',')
        default:
            //What?
            panic("Unsupported")
        }
    }
}

Since we are concating a lot of strings here, I used the strings.Builder for string building. b.WriteString(x) is just appeding x to the tail of the string b holds.

And because we now use a strings.builder and a prefix, so I write a function to wrap it:

func parsecustom(aMap map[string]interface{}) string {
    b:=&strings.Builder{}
    parseMap(aMap,"",b)

    return strings.TrimSuffix(b.String(),",")
}

Now if you run fmt.Println(parsecustom(data)), you can get output: x=4 ,z.t=8 ,z.y=6 ,a.b.p=0 ,m.c=4 as desired.

Full example: https://play.golang.org/p/_QIp2LRYjm7

like image 99
leaf bebop Avatar answered Sep 29 '26 18:09

leaf bebop



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!