关于字典:检查一个条件下多个映射中是否存在密钥

Check if key exists in multiple maps in one condition

我需要检查两个地图中是否存在相同的键:

1
2
3
4
5
6
if v1, ok1 := map1["aaa"]; ok1 {
 ...
}
if v2, ok2 := map2["aaa"]; ok2 {
 ...
}

是否可以将这两个条件合并为一个条件?我设法做到了这样:

1
2
3
4
5
v1, ok1 := map1["aaa"]
v2, ok2 := map2["aaa"]
if ok1 && ok2 {
 ...
}

但我很好奇(分配和检查)是否可以在一个if条件下完成。


不,不行。规范:索引表达式:

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

1
2
3
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.

因此,只有在没有其他分配的情况下,才可以使用特殊的v, ok := m[k]表单。

但是,如果不使用映射值类型的零值,则可以使用简单的元组赋值进行检查;不使用特殊形式,而是使用2个简单的索引表达式。

例如,如果您的值类型是某种接口类型(例如,interface{}),并且您知道您不使用nil值,则可以执行以下操作:

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

当然,使用helper函数,只需一步:

1
2
3
4
5
6
7
func idx(m1, m2 map[string]interface{}, k string) (
    v1, v2 interface{}, ok1, ok2 bool) {

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

使用它:

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

在游乐场上尝试这些例子。


您还可以使用变量参数(三个点)检查多个键:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 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
}

然后您可以按如下顺序检查您的钥匙:

1
2
3
4
5
6
7
8
9
10
11
result := checkMap(myMap, myMap2,"a","b","c","d","e","f","g")
fmt.Printf("result = %+v
", 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")
}