Maps in Go – how to avoid double key lookup?

huangapple go评论67阅读模式
英文:

Maps in Go - how to avoid double key lookup?

问题

假设我想要在一个映射中更新某个现有的值,或者在找不到键时执行其他操作。我该如何做到这一点,而不需要进行两次查找?以下是相应的Go语言代码:

value, ok := m[key]
if ok {
    // 更新值,无需进行第二次查找
    m[key] = calcNewValue(value)
} else {
    // 执行其他操作
    m[key] = 42
}

在Go语言中,使用map[key]的方式可以直接获取映射中的值,并通过ok变量来判断是否找到了对应的键。如果找到了键,则可以直接更新值;如果未找到键,则可以执行其他操作,例如插入新的键值对。

英文:

Suppose I want to update some existing value in a map, or do something else if the key is not found. How do I do this, without performing 2 lookups? What's the golang equivalent of the following C++ code:

auto it = m.find(key);
if (it != m.end()) {
    // update the value, without performing a second lookup
    it->second = calc_new_value(it->second);
} else {
    // do something else
    m.insert(make_pair(key, 42));
}

答案1

得分: 5

Go语言不像C++那样公开映射的内部(key,value)对数据结构,因此无法完全复制这一点。

一种可能的解决方法是将映射的值设置为指针,这样可以保持映射中的相同值,但可以更新它们指向的内容。例如,如果m是一个map[int]*int,你可以通过以下方式更改一个值:

v := m[10]
*v = 42

话虽如此,如果减少哈希查找次数所带来的节省被额外的内存管理开销所消耗,我不会感到惊讶。因此,值得对你选择的任何解决方案进行基准测试。

英文:

Go does not expose the map's internal (key,value) pair data structure like C++ does, so you can't replicate this exactly.

One possible work around would be to make the values of your map pointers, so you can keep the same values in the map but update what they point to. For example, if m is a map[int]*int, you could change a value with:

v := m[10]
*v = 42

With that said, I wouldn't be surprised if the savings from reducing the number of hash lookups will be eaten by the additional memory management overhead. So it would be worth benchmarking whatever solution you settle on.

答案2

得分: 2

你不能。实际上,这种情况与Python的字典相同。然而,这并不重要。在Go语言中,查找和赋值都是摊还O(1)的时间复杂度。将这两个操作结合起来的时间复杂度也是相同的。

英文:

You cannot. The situation is actually the same with Python dicts. However it shouldn't matter. Both lookup and assignment to a Go map are amortized O(1). Combining the two operations has the same time complexity.

huangapple
  • 本文由 发表于 2015年1月19日 08:38:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/28016484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定