如何在Golang中从嵌套的映射中删除完全匹配的数据

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

How to delete exact matched data from nested map in golang

问题

我正在使用嵌套的映射数据结构(map[string]map[string]map[string]string-map[ip]map[port]map[path]string)在golang项目中使用IM缓存。对于一个IP地址,可以向映射中添加多个端口和路径值的组合。现在的问题是,我需要从上述嵌套映射值中删除确切的ip,port,path组合。以下是代码示例。我计划从映射中删除http://10.3.5.6:8080/path7。

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"] = "/path7"
	delete(cacheEntries, delVal)
	fmt.Println(cacheEntries)
}

上述代码会抛出编译错误,错误信息为**./prog.go:21:23: cannot use delVal (variable of type map[string]map[string]string) as type string in argument to delete**,这是因为delete函数只接受字符串类型的值作为参数。请问有什么建议来解决上述问题,或者有其他推荐的解决方法吗?

提前感谢您的帮助。

英文:

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, for one ip there is a multiple combination of port, path values can be added to the map, here is the concern, I have to delete the exact combination of ip,port,path from the above nested map values. Below I am attaching the code. I am planning to delete http://10.3.5.6:8080/path7 from the map.

**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"] = "/path7"
	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.

答案1

得分: 1

首先,由于没有条目"/path",我会假设你指的是"/path7"。

其次,要删除地图中的一个键,你只需要引用现有的地图,而不是重新创建它。

请参见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)
}

结果:

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]]]

要删除一个精确的元组(IP、端口、路径),请参见此示例

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)
	del("http://10.3.5.6", "8080", "/path7", cacheEntries)
	fmt.Println(cacheEntries)
}

func del(ip, port, path string, cacheEntries cacheData) {
	mapIP := cacheEntries[ip]
	if mapIP == nil {
		return
	}
	mapPort := mapIP[port]
	if mapPort == nil {
		return
	}
	delete(mapPort, path)
	if len(mapPort) == 0 {
		delete(mapIP, port)
	}
	if len(mapIP) == 0 {
		delete(cacheEntries, ip)
	}
}

结果:

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.7:map[8080:map[/path7:URL]]]
英文:

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]]]

For deleting an exact tuple (IP, port, path), see this example:

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)
	del("http://10.3.5.6", "8080", "/path7", cacheEntries)
	fmt.Println(cacheEntries)
}

func del(ip, port, path string, cacheEntries cacheData) {
	mapIP := cacheEntries[ip]
	if mapIP == nil {
		return
	}
	mapPort := mapIP[port]
	if mapPort == nil {
		return
	}
	delete(mapPort, path)
	if len(mapPort) == 0 {
		delete(mapIP, port)
	}
	if len(mapIP) == 0 {
		delete(cacheEntries, ip)
	}
}

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.7:map[8080:map[/path7:URL]]]

huangapple
  • 本文由 发表于 2022年10月17日 10:35:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/74092090.html
匿名

发表评论

匿名网友

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

确定