Check if a map is subset of another map


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 (

func main() {
    a := map[string]string{"a": "b", "c": "d", "e": "f"}
    b := map[string]string{"a": "b", "e": "f"}
    c := IsMapSubset(a, b)

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 a reflect.Value which is a struct, and nil is not a valid value for structs. You can’t compare a struct value to nil.

Value.MapIndex() states that:

It returns the zero Value if key is not found in the map or if v represents a nil map.

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 the Value.IsValid() method.

You also can’t (shouldn’t) compare reflect.Value values. Instead obtain their wrapped value using Value.Interface(), and compare those.

if v2 := mapSetValue.MapIndex(k); !v2.IsValid() || v.Interface() != v2.Interface() {
    return false

Testing it:

a := map[string]string{"a": "b", "c": "d", "e": "f"}
b := map[string]string{"a": "b", "e": "f"}
fmt.Println(IsMapSubset(a, b))

c := map[string]string{"a": "b", "e": "X"}
fmt.Println(IsMapSubset(a, c))

Output will be (try it on the Go Playground):


Answered By – icza

Answer Checked By – Mildred Charles (GoLangFix Admin)

Leave a Reply

Your email address will not be published.