This question is already answered in many other languages. In golang with simple maps (no nesting) how to find out if a map is subset of another. for example: map[string]string{"a": "b", "e": "f"}
is subset of map[string]string{"a": "b", "c": "d", "e": "f"}
. I want a generic method. My code:
package main
import (
"fmt"
"reflect"
)
func main() {
a := map[string]string{"a": "b", "c": "d", "e": "f"}
b := map[string]string{"a": "b", "e": "f"}
c := IsMapSubset(a, b)
fmt.Println(c)
}
func IsMapSubset(mapSet interface{}, mapSubset interface{}) bool {
mapSetValue := reflect.ValueOf(mapSet)
mapSubsetValue := reflect.ValueOf(mapSubset)
if mapSetValue.Kind() != reflect.Map || mapSubsetValue.Kind() != reflect.Map {
return false
}
if reflect.TypeOf(mapSetValue) != reflect.TypeOf(mapSubsetValue) {
return false
}
if len(mapSubsetValue.MapKeys()) == 0 {
return true
}
iterMapSubset := mapSubsetValue.MapRange()
for iterMapSubset.Next() {
k := iterMapSubset.Key()
v := iterMapSubset.Value()
if value := mapSetValue.MapIndex(k); value == nil || v != value { // invalid: value == nil
return false
}
}
return true
}
When I want to check if subset map key exists in set map, MapIndex
returns zero value of type and make it impossible to compare it with anything.
Afterall can I do the same job better?
Value.MapIndex()
returns areflect.Value
which is a struct, andnil
is not a valid value for structs. You can't compare a struct value tonil
.Value.MapIndex()
states that:So to tell if the key was not found in the map, check if the returned
reflect.Value
is its zero value. For that you may use theValue.IsValid()
method.You also can't (shouldn't) compare
reflect.Value
values. Instead obtain their wrapped value usingValue.Interface()
, and compare those.Testing it:
Output will be (try it on the Go Playground):