With
m := map[string]any{"a": 1, "b": 2, "c": []int{2, 3, 4}}
v := reflect.ValueOf(m)
How to iterate through "c"
in v
?
See /play/p/KQ_UNjm-Vqd
package main
import (
"fmt"
"reflect"
)
func main() {
m := map[string]any{"a": 1, "b": 2, "c": []int{2, 3, 4}}
v := reflect.ValueOf(m)
// Access the "c" key
cKey := reflect.ValueOf("c")
cValue := v.MapIndex(cKey)
if cValue.IsValid() && cValue.Kind() == reflect.Slice {
fmt.Println("Iterating through 'c':")
for i := 0; i < cValue.Len(); i++ {
fmt.Println(cValue.Index(i).Interface())
}
} else {
fmt.Println("'c' is not a valid slice or key does not exist.")
}
if !cValue.IsValid() {
fmt.Println("Key 'c' not found in the map")
return
}
if cValue.Kind() != reflect.Slice {
fmt.Println("Value for key 'c' is not a slice")
return
}
}
With
m := map[string]any{"a": 1, "b": 2, "c": []int{2, 3, 4}}
v := reflect.ValueOf(m)
How to iterate through "c"
in v
?
See https://go.dev/play/p/KQ_UNjm-Vqd
package main
import (
"fmt"
"reflect"
)
func main() {
m := map[string]any{"a": 1, "b": 2, "c": []int{2, 3, 4}}
v := reflect.ValueOf(m)
// Access the "c" key
cKey := reflect.ValueOf("c")
cValue := v.MapIndex(cKey)
if cValue.IsValid() && cValue.Kind() == reflect.Slice {
fmt.Println("Iterating through 'c':")
for i := 0; i < cValue.Len(); i++ {
fmt.Println(cValue.Index(i).Interface())
}
} else {
fmt.Println("'c' is not a valid slice or key does not exist.")
}
if !cValue.IsValid() {
fmt.Println("Key 'c' not found in the map")
return
}
if cValue.Kind() != reflect.Slice {
fmt.Println("Value for key 'c' is not a slice")
return
}
}
(I spent way too long in this)
package main
import (
"fmt"
"reflect"
)
func main() {
m := map[string]any{"a": 1, "b": 2, "c": []int{2, 3, 4}}
v := reflect.ValueOf(m)
// Access the "c" key
cKey := reflect.ValueOf("c")
cValue := v.MapIndex(cKey)
if !cValue.IsValid() {
fmt.Println("Key 'c' not found in the map. ")
return
}
// If the value is an interface, unwrap it
if cValue.Kind() == reflect.Interface {
cValue = cValue.Elem()
}
if cValue.Kind() != reflect.Slice {
fmt.Println("Value for key 'c' is not a slice. ")
return
}
fmt.Println("Iterating... ")
for i := 0; i < cValue.Len(); i++ {
fmt.Printf("Element %d: %v\n", i, cValue.Index(i).Interface())
}
}
To iterate over a reflect.Value
representing a Map
, we can utilize the MapKeys
method from the reflect
package. Here's a complete example:
// Check if the reflect.Value represents a Map
if v.Kind() == reflect.Map {
// Get all the keys in the map as a slice of reflect.Value
keys := v.MapKeys()
for _, key := range keys {
// Convert the reflect.Value representation of the key back to its original type
keyStr, ok := key.Interface().(string)
if !ok {
fmt.Printf("Key is not a string: %v\n", key)
continue
}
// Retrieve the value associated with the key
value := v.MapIndex(key)
// Extract the underlying value from reflect.Value and print the key-value pair
fmt.Printf("Key: %s, Value: %v\n", keyStr, value.Interface())
}
} else {
fmt.Println("v is not a map")
}
Live Code
Key Points
MapKeys()
or MapIndex()
will panic on non-map valuesSources:
Reflect.Value
docsReflect.MapKeys
docsReflect.MapIndex
docs
cValue
represents the interface, not the underlying slice - use.Elem()
to get aValue
for the underlying slice. There's gotta be a dupe around here somewhere, but I'm not familiar with the standard Go dupe targets. – user2357112 Commented Jan 2 at 3:09"c"
? Only that it's a slice of some unknown element type? Or do you also know that the element type isint
? Because, in the latter case, you don't need reflection; a simple type assertion will do. – jub0bs Commented Jan 2 at 9:53int
is for demo and simplicity only. The actualc
is a json struct that I haven't able to exhaust all its possible fields yet. – xpt Commented Jan 3 at 0:17