繁体   English   中英

如何在 Go 中更新地图值

[英]How to update map values in Go

我想用字符串键和结构值构建一个映射,我可以用它来更新映射键标识的映射中的结构值。

我试过这个这个并没有给我想要的输出。

我真正想要的是:

Received ID: D1 Value: V1
Received ID: D2 Value: V2
Received ID: D3 Value: V3
Received ID: D4 Value: V4
Received ID: D5 Value: V5

Data key: D1 Value: UpdatedData for D1
Data key: D2 Value: UpdatedData for D2
Data key: D3 Value: UpdatedData for D3
Data key: D4 Value: UpdatedData for D4
Data key: D5 Value: UpdatedData for D5

Data key: D1 Value: UpdatedData for D1
Data key: D2 Value: UpdatedData for D2
Data key: D3 Value: UpdatedData for D3
Data key: D4 Value: UpdatedData for D4
Data key: D5 Value: UpdatedData for D5

您不能更改与地图中的键关联的值,只能重新分配值。

这为您留下了 2 种可能性:

  1. 将指针存储在地图中,以便您可以修改指向的对象(不在地图数据结构内)。

  2. 存储结构值,但是当你修改它时,你需要将它重新分配给键。

1. 使用指针

在地图中存储指针: dataManaged := map[string]*Data{}

当你“填充”地图时,你不能使用循环的变量,因为它在每次迭代中都会被覆盖。 而是制作一个副本,并存储该副本的地址:

for _, v := range dataReceived {
    fmt.Println("Received ID:", v.ID, "Value:", v.Value)
    v2 := v
    dataManaged[v.ID] = &v2
}

输出符合预期。 Go Playground上尝试一下。

2.重新分配修改后的结构

坚持在地图中存储结构值: dataManaged := map[string]Data{}

遍历键值对将为您提供值的副本。 因此,在您修改值后,将其重新分配:

for m, n := range dataManaged {
    n.Value = "UpdatedData for " + n.ID
    dataManaged[m] = n
    fmt.Println("Data key:", m, "Value:", n.Value)
}

Go Playground上试试这个。

我正在学习 Golang,谷歌把我带到了这里。 一种方法是创建一个 DataStore 结构。 我想出了这个[见这里][1]。 请让我知道这是否是一个好方法。


import (
    "fmt"
)

type Data struct {
    key   string
    value string
}

type DataStore struct {
    datastore map[string]Data
}

func newDataStore() DataStore {
    return DataStore{make(map[string]Data)}
}

/*
Puts the key and value in the DataStore.
If the key (k) already exists will replace with the provided value (v).
*/
func (ds *DataStore) put(k, v string) {
    dx := Data{key: k, value: v}
    ds.datastore[k] = dx
}

/*
Returns true, if the DataStore has the key (k)
*/
func (ds *DataStore) containsKey(k string) bool {
    if _, ok := ds.datastore[k]; ok {
        return ok
    }
    return false
}

/*
Puts the key and value in the DataStore, ONLY if the key (k) is not present.
Returns true, if the put operation is successful,
false if the key (k) ia already present in the DataStore
*/
func (ds *DataStore) putIfAbsent(k, v string) bool {
    if val, ok := ds.datastore[k]; ok {
        fmt.Println("datastore contains key: ", k, "with value =", val, " --- ", ok)
        return false
    }

    fmt.Println("datastore does not contain ", k)
    dx := Data{key: k, value: v}
    ds.datastore[k] = dx
    return true
}

/*
Returns the Data value associated with the key (k).
*/
func (ds *DataStore) get(k string) Data {
    return ds.datastore[k]
}

/*
Removes the entry for the given key(k)
*/
func (ds *DataStore) removeKey(k string) {
    delete(ds.datastore, k)
}

/*
Removes the entry for the given key(k)
*/
func (ds *DataStore) removeKeys(k ...string) {
    for _, d := range k {
        delete(ds.datastore, d)
    }
}

/*
Prints the keys and values
*/
func (ds *DataStore) print() {
    for k, v := range ds.datastore {
        fmt.Println(k, " ", v)
    }
}

func main() {
    fmt.Println("Hello, playground")
    ds := newDataStore()
    ds.print()
    ds.put("D1", "V1")
    ds.put("D2", "V2")
    ds.put("D3", "V3")  
    fmt.Println("datastore with initial values")

    ds.print()

    ds.put("D1", "UpdatedData for D1")
    ds.put("D2", "UpdatedData for D2")
    ds.put("D3", "UpdatedData for D3")
    fmt.Println("datastore with updated values")

    ds.print()
    
    fmt.Println("datastore: putIfAbsent");
    ds.putIfAbsent("D3", "Duplicate Key")
    ds.putIfAbsent("D4", "V4")
    ds.putIfAbsent("D5", "V5")
    
    fmt.Println("datastore with new values")

    result := ds.get("D1")
    fmt.Println("fetching the value for D1: result: ", result)

    testKey := "D4"
    //testKeys := [2]string{"D5", "D2"}
    
    fmt.Println("datastore: containsKey: ")

    if ok := ds.containsKey(testKey); ok {
        fmt.Println("has key ", testKey, ok)
    } else {
        fmt.Println("has no key ", testKey, ok)
    }

    ds.print()
    ds.removeKey(testKey)

    fmt.Println("afer removing ", testKey)
    ds.print()

    fmt.Println("afer removing ", "D5", "D1")
    ds.removeKeys("D5", "D1")
    ds.print()
}```



  [1]: https://play.golang.org/p/4FEGkImcCKB

问题是关于 struct 的,但是我在搜索“如果键存在时如何更新键,或者如果键不存在则插入它”时找到了它。

我有一个映射T -> number ,我想计算一个键在数组或切片中出现的次数:

    data := []int{0,0,0,1,1,2,3,3,3,3,4}
    m := make(map[int]int, 0)
    for _, val := range data {
        m[val] = m[val] + 1
    }

工作原理:如果键不存在,则m[val]生成映射值类型的“零”形式。 对于数值,这是0 然后我添加1 ,并再次存储在插槽m[val] 这是完美的第一个值。

当密钥不存在时会发生什么:

1. m[val] = m[val] + 1
2. m[val] = 0 + 1
3. m[val] = 1

当key存在时会发生什么:

1. m[val] = m[val] + 1
2. m[val] = 1 + 1
3. m[val] = 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM