I am using IM cache with nested map data structure(map[string]map[string]map[string]string-map[ip]map[port]map[path]string) in the golang project, here is the concern, I have to delete the exact combination from the above nested map values whenever data deleted from the database. below I am attaching the code.
**package main
import "fmt"
type cacheData map[string]map[string]map[string]string
func main() {
cacheEntries := make(cacheData)
cacheEntries["http://10.3.5.6"] = make(map[string]map[string]string)
cacheEntries["http://10.3.5.6"]["8080"] = make(map[string]string)
cacheEntries["http://10.3.5.6"]["8080"]["/path7"] = "URL"
cacheEntries["http://10.3.5.7"] = make(map[string]map[string]string)
cacheEntries["http://10.3.5.7"]["8080"] = make(map[string]string)
cacheEntries["http://10.3.5.7"]["8080"]["/path7"] = "URL"
fmt.Println(cacheEntries)
delVal := make(map[string]map[string]string)
delVal["http://10.3.5.6"] = make(map[string]string)
delVal["http://10.3.5.6"]["8080"] = "/path"
delete(cacheEntries, delVal)
fmt.Println(cacheEntries)
}**
The above code is throwing compilation error saying ./prog.go:21:23: cannot use delVal (variable of type map[string]map[string]string) as type string in argument to delete , this is because delete function only expects string value for delete. Any suggestion to solve the above problem or any other approaches recommended to solve please let me know.
Thanks in advance.
CodePudding user response:
It doesn't matter if the map is nested. The builtin delete
function takes as arguments a map and a key.
If the map that contains the key to delete is inside a N-levels deep map of maps, just write an expression that yields it as you normally would:
delete(cacheEntries["http://10.3.5.6"]["8080"], "/path")
// ^ main map ^ 2nd map ^ 3rd map
which is equivalent to:
m := cacheEntries["http://10.3.5.6"]["8080"]
delete(m, "/path")
Incidentally, chaining the index operators with multiple maps is safe. If one key is not found, it yields a nil
map, but indexing a nil
map doesn't panic:
if the map is
nil
or does not contain such an entry, a[x] is the zero value for the element type of M
CodePudding user response:
First, since there is no entry "/path
", I would assume you meant "/path7
"
Second, to delete a key in a map, you simply need to reference the existing map, not to recreate it.
See playground
package main
import "fmt"
type cacheData map[string]map[string]map[string]string
func main() {
cacheEntries := make(cacheData)
cacheEntries["http://10.3.5.6"] = make(map[string]map[string]string)
cacheEntries["http://10.3.5.6"]["8080"] = make(map[string]string)
cacheEntries["http://10.3.5.6"]["8080"]["/path7"] = "URL"
cacheEntries["http://10.3.5.7"] = make(map[string]map[string]string)
cacheEntries["http://10.3.5.7"]["8080"] = make(map[string]string)
cacheEntries["http://10.3.5.7"]["8080"]["/path7"] = "URL"
fmt.Println(cacheEntries)
delMap := cacheEntries["http://10.3.5.6"]["8080"]
delVal := "/path7"
delete(delMap, delVal)
fmt.Println(cacheEntries)
}
Result:
map[http://10.3.5.6:map[8080:map[/path7:URL]] http://10.3.5.7:map[8080:map[/path7:URL]]]
map[http://10.3.5.6:map[8080:map[]] http://10.3.5.7:map[8080:map[/path7:URL]]]