【问题标题】:Check if key exists in multiple maps in one condition在一个条件下检查键是否存在于多个映射中
【发布时间】:2017-06-18 02:25:23
【问题描述】:

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

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

这两个条件可以合二为一吗?我设法做这样的事情:

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

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

【问题讨论】:

    标签: dictionary go


    【解决方案1】:

    不,不能这样做。 Spec: Index expressions:

    map[K]V 类型的映射 a 上的索引表达式用于 assignment 或特殊形式的初始化

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

    产生一个额外的无类型布尔值。如果映射中存在键 x,则 ok 的值为 true,否则为 false。

    因此,只有在没有分配任何其他内容的情况下,您才能使用特殊的 v, ok := m[k] 表单。

    但是,如果不使用map的值类型zero value,可以使用简单的tuple-assignment进行检查;不使用特殊形式,而是使用 2 个简单的索引表达式。

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

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

    当然有了辅助函数,一步就能搞定:

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

    使用它:

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

    尝试Go Playground 上的示例。

    【讨论】:

    • 对 golang 来说相对较新,我不得不说if v1, v2, ok1, ok2 := idx(m1, m2, "aaa"); ok1 && ok2 { 看起来像是眼内黑色素瘤的一个危险因素。又名眼癌。
    • @jangroth 我也不会使用它,但可以按照提问者的意愿去做。
    【解决方案2】:

    你也可以使用可变参数(三个点)来检查多个键:

    // 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
    }
    

    然后你可以像这样检查你的钥匙:

    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")
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多