I'd like to write a function which accepts a slice of keys and returns the result of traversing a map for each of those keys.
For example, given this map:
m := map[string]interface{}{
"apples": []string{"delicious", "green", "red"},
"oranges": map[string]interface{}{
"foo": 123456,
"bar": "hello, world",
},
}
we can get the value of the "bar"
key in the "oranges"
map by writing:
m["oranges"].(map[string]interface{})["bar"]
We can continue getting at deeply nested keys with the general approach of:
m["first-key"]
.(map[string]interface{})["second-key"]
.(map[string]interface{})["third-key"]
{...}
Now imagine that we have a slice that represents the strings forming the deeply-nested key (e.g. ["oranges", "bar"]
), and a map we want to traverse.
Is there a way to write a function which does that? Here's a Go Playground link that I've been working from.
评论:
1lann:
DavidDavidsonsGhost:Sure you can, using recursion: https://play.golang.org/p/0-CKUVYsE4
And one using iteration: https://play.golang.org/p/7ze54Hp9vi
Redundancy_:I prefer your first one, but a type switch is a little cleaner I think: https://play.golang.org/p/zGAA5caVEk
jxf:As a gentle counterpoint to being able to do it - can you not structure the data better so that it's well-typed and has a semantically consistent meaning?
I realize that this isn't always possible with other people's APIs etc.
garaktailor:The map is the result of getting YAML back from a parser in use by a library that I don't control. Since, by definition, YAML represents arbitrarily structured data, it's hard to get more strongly typed than
map[string]interface{}
without becoming unwieldy.
MohamedBassem:How about this: https://play.golang.org/p/WBE14HCqZw
I use something like this when dealing with json that I don't necessarily have a nice schema for.
Some people already answered but I was writing it anyways, so here you go : https://play.golang.org/p/cYldrwU3KA
