10
votes

I need to check if the same key exists in two maps:

if v1, ok1 := map1["aaa"]; ok1 {
 ...
}
if v2, ok2 := map2["aaa"]; ok2 {
 ...
}

Is it possible to join these two conditions into one? I managed to do something like this:

v1, ok1 := map1["aaa"]
v2, ok2 := map2["aaa"]
if ok1 && ok2 {
 ...
}

but I'm curious whether it (assigning and checking) can be done in one if condition.

2

2 Answers

8
votes

No, it can't be done. Spec: Index expressions:

An index expression on a map a of type map[K]V used in an assignment or initialization of the special form

v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]

yields an additional untyped boolean value. The value of ok is true if the key x is present in the map, and false otherwise.

So you can use the special v, ok := m[k] form only if nothing else gets assigned.

However, if you don't use the zero value of the value type of the map, you can do the check using a simple tuple-assignment; by not using the special form but 2 simple index expressions.

For example if your value type is some interface type (e.g. interface{}), and you know you don't use the nil value, you may do the following:

if v1, v2 := m1["aaa"], m2["aaa"]; v1 != nil && v2 != nil {
    fmt.Printf("Both map contains key '%s': %v, %v\n", "aaa", v1, v2)
}

Of course with a helper function, you can do it in one step:

func idx(m1, m2 map[string]interface{}, k string) (
    v1, v2 interface{}, ok1, ok2 bool) {

    v1, ok1 = m1[k]
    v2, ok2 = m2[k]
    return
}

Using it:

if v1, v2, ok1, ok2 := idx(m1, m2, "aaa"); ok1 && ok2 {
    fmt.Printf("Both map contains key '%s': %v, %v\n", "aaa", v1, v2)
}

Try the examples on the Go Playground.

0
votes

you could also use variadic parameter(three dots) to check multiple keys :

// check map 1 and map2 is null or not
func checkMap(m1, m2 map[string]interface{}, keys ...string) []bool {
    var isExist []bool

    for key := range keys {
        //checking value from map 1
        _, ok := m1[keys[key]]
        if ok {
            isExist = append(isExist, true) // append for the first time to avoid panic
        } else {
            isExist = append(isExist, false) // append for the first time to avoid panic
        }

        // checking value from map2
        _, ok = m2[keys[key]]
        if ok {
            isExist[key] = true
        } else {
            isExist[key] = false
        }
    }

    return isExist
}

And then you can check your keys in order like this :

result := checkMap(myMap, myMap2, "a", "b", "c", "d", "e", "f", "g")
fmt.Printf("result = %+v\n", result) // print the result

if result[0] {
    fmt.Println("key a exist in both map")
}

if result[1] {
    fmt.Println("key b exist in both map")
}