Reputation: 384
I have a nested map with lower
case characters. What I want to do is to iterate on the map and convert all the keys to Title
case. I tried the following code below, but it is giving me weird results. Can someone guide me where I am going wrong?
package main
import (
"fmt"
"strings"
)
func main() {
a := make(map[string]interface{})
a["start"] = map[string]interface{}{
"hello": 2,
"world": 3,
"here": map[string]interface{}{
"baam": 123,
"boom": "dsd",
},
}
printMap(a)
fmt.Println(a)
}
func printMap(a map[string]interface{}) {
for k, v := range a {
switch v.(type) {
case map[string]interface{}:
printMap(v.(map[string]interface{}))
default:
title := strings.Title(k)
a[title] = a[k]
delete(a, k)
}
}
}
Upvotes: 0
Views: 4776
Reputation: 51497
The problem is you are iterating a map and changing it at the same time, but expecting the iteration would not see what you did. The relevant part of the code is:
for k, v := range a {
title := strings.Title(k)
a[title] = a[k]
delete(a, k)
}
So if the map has {"hello":2, "world":3}
, and assume the keys are iterated in that order. After the first iteration, you now have:
{"world":3, "Hello":2}
Next iteration:
{"World":3, "Hello":2}
Next iteration looks at "Hello", which is already capitalized, so you capitalize it again, and then delete it, ending up with:
{"World":3}
You might want to produce a new map instead of overwriting the existing one, and return that so the caller can use it instead.
func main() {
a := make(map[string]interface{})
a["start"] = map[string]interface{}{
"hello": 2,
"world": 3,
"here": map[string]interface{}{
"baam": 123,
"boom": "dsd",
},
}
a=printMap(a)
fmt.Println(a)
}
func printMap(a map[string]interface{}) map[string]interface{} {
newMap:=map[string]interface{}{}
for k, v := range a {
switch v.(type) {
case map[string]interface{}:
newMap[k]=printMap(v.(map[string]interface{}))
default:
title := strings.Title(k)
newMap[title] = a[k]
}
}
return newMap
}
Upvotes: 6