go - 我可以在没有两次索引调用的情况下同时更新和检索 Map 中的元素吗?

标签 go hashmap

我有一张包含整数值的 map 。我想更新一个值,然后检查更新后的值是否超过阈值。

如果我不需要检查新值,那么我会简单地做

map[key] += 1

如果我想检查新值,明显的变化是:

old_val := map[key]
new_val := old_val + 1
map[key] = new_val
if (new_val > threshold) {
    return
}

但是,这对 map 进行了两次索引调用,这不一定是常量时间操作。

我想做的是:

val_p := &(map[key])
*(val_p) += 1
if (*(val_p) > threshold) {
    return
}

但是,GoLang 映射在设计上是不可寻址的,因为地址显然可以改变(尽管在这种情况下它不会改变,因为我没有改变映射)。

是否有一些函数可以用来更新返回新值的 map 中的元素?专门针对整数?

最佳答案

由于您在问题中提到的原因,您不能使用“简单”值来做到这一点。

你可能做的是在映射中存储一个包装器或一个指针,所以你只需要查找值,而且你只需要做一次;更改数据会更改 map 外的指向值,因此您不必重新分配(指针不会更改)。

例如:

const threshold = 3

m := map[string]*int{
    "one": new(int),
}

for {
    p := m["one"]
    fmt.Println("data=", *p)
    *p++
    if *p > threshold {
        fmt.Println("threshold reached", *p)
        break
    }
}

此输出(在 Go Playground 上尝试):

data= 0
data= 1
data= 2
data= 3
threshold reached 4

尽管请注意,由于指针间接寻址,这可能不会更快。衡量这是否是您应用的关键部分。

关于go - 我可以在没有两次索引调用的情况下同时更新和检索 Map 中的元素吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55283372/

相关文章:

android - 包中没有导出的名称 "src/github.com/rohankeskar19/android_whisper"

java - 如何处理 HashMap 中相同的键?

java - 如何迭代速度模板中的嵌套 map ?

java - 解析JSON并将其放入HashMap中

bash - 无法在 elementary os loki 中设置 GOPATH

angularjs - Beego框架如何设置Access-Control-Allow-Origin

java - 为什么 HashSet 不能直接在内部使用位数组而不是 HashMap 来节省一些空间?

java - 为什么 Map 的 containsKey() 只调用 hashCode()?

Goland 读取每行命令输出的衬垫

go - 如何处理外面的 panic