godata-structuresmapsnested-map

How to delete exact matched data from nested map in golang


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.


Solution

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