Sunday 17 October 2021

[Golang] How To Work With Maps In Golang Tutorial

What is Map In Golang?

Maps are a convenient and powerful built-in data structure that associate values of one type (the key) with values of another type (the element or value). The key can be of any type for which the equality operator is defined, such as integers, floating point and complex numbers, strings, pointers, interfaces (as long as the dynamic type supports equality), structs and arrays. Slices cannot be used as map keys, because equality is not defined on them. Like slices, maps hold references to an underlying data structure. If you pass a map to a function that changes the contents of the map, the changes will be visible in the caller.

Maps can be constructed using the usual composite literal syntax with colon-separated key-value pairs, so it's easy to build them during initialization.

For more context you can compare golangs' map as pythons' dictionary and as well nodejs' object.


How to Create Map?

A map can be created by passing the type of key and value to the make function and as well as using direct way with map keyword. The following is the syntax to create a new map with make.

make(map[type of key]type of value)  
map[type of key]type of value{}
usersVisited := make(map[string]int)


The Above he have created a map with the help of make function which is usersVisited so this map is going to store the values via ip and count of that ip's visits as int each time we're going to increase that number whenever some request comes from the ip which exists in usersVisited map.



    package main

    import "fmt"

    func main() {
        usersVisited := make(map[string]int)
        fmt.Println(usersVisited)
    }



So this is the code to declare the map let's run it and check what result it gives us.

map[]
we haven't added any key and value yet so the output of the map is empty.


Let's Add Key and Values in Map

The Syntax for adding new item in map is same as we do for the arrays and slices.
The Program below adds some new entries in usersVisited map.

    
    package main

    import "fmt"

    func main() {
        usersVisited := make(map[string]int)
        usersVisited["127.0.0.1"] = 1
        usersVisited["127.0.0.2"] = 2
        usersVisited["127.0.0.3"] = 3
        usersVisited["127.0.0.4"] = 4
        fmt.Println(usersVisited)    
    }




We have added four testing entries and the corresponding counts as well as.

The above program prints

map[127.0.0.1:1 127.0.0.2:2 127.0.0.3:3 127.0.0.4:4]

Initialization and Declaration At the Same Time.

It is possible us to initialize and declare the map at the same time in golang as we have code above for declaration.

Let's see the code for this step

    
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        fmt.Println(usersVisited)
    }




The above program declares usersVisited map and adds four entries in it as well.

Note: You can  Add more keys and values after declaration and initialization as well, As we did before this example


Note : You can use any data type which exists in golang as your key and value type it depends on us which type's requirement we have, even you can use interfaces and structs as well. 


Zero Value of a Map

Zero value of a map is nil, and it if you try to add entries in nil map it can cause error or you can say a panic error. Hence the map has to be initialize before adding any entries or key and values in it.

Let's check which type of error it will going to give us.

    
    package main

    import "fmt"

    func main() {
        var usersVisited map[string]int
        usersVisited["127.0.0.1"] = 1
        fmt.Println(usersVisited)
    }




In the above program we are adding new key and value into usersVisited map.

Now Let's Check the output of it.

panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        C:/Users/Kuldeep/Desktop/Youtube/golang-map/n.go:7 +0x56
exit status 2
So we have got the panic which pointing to the same issue as we thought


Retrieving Values from Map using Keys

We already have added few entries in our code so let's try to retrieve counts of each ip using the keys(ip string).

Syntax is to retrieve values from map is map[key].

Let's write the code for more context.

    
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        ip := "127.0.0.4"

        visitedCount := usersVisited[ip]
        fmt.Printf("IP %s\n%d Times Visited", ip, visitedCount)
    }



The code written above is simple. We have a ip address and we are just passing ip address into map and getting the count from it for that passed ip address.

IP 127.0.0.4
4 Times Visited

Key Not Exists In Map

So in this case we are about to check what output or error we are going to get if the key we passes to the map is not exists in map.

  
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        ip := "127.0.0.5"

        visitedCount := usersVisited[ip]
        fmt.Printf("IP %s\n%d Times Visited", ip, visitedCount)
    }



So the code written above is just doing the same process as we learn before, just passing key but this key isn't exists.

Let's see the output

IP 127.0.0.5
0 Times Visited
So the output of this is 0 for that so now we knows for non existing keys map doesn't gives any error just returns the empty as we have passes int type that's why it's zero if you try with string it will going to return blank or empty value for string.


Checking if Key Exists

In the above section we learned that when a key is not present, the zero value of the type will be returned. This doesn't help when we want to find out whether the key actually exists in the map.


For example we want to know if key exists in usersVisited maps or not so we can follow this step.

value, exists := map[key] 

The above code is the syntax to check if a key exists in a map. if it exists the the exists variable will be going to true and the value of that key is store in value variable as we have in above syntax.

    
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        ip := "127.0.0.5"

        visitedCount, exists := usersVisited[ip]
        if !exists {
            fmt.Printf("%s key not found", ip)
            return
        }
        fmt.Printf("IP %s\n%d Times Visited", ip, visitedCount)
    }




In the above code you can see we have added the same step to get the value and as well as to check if it exists or not.

We have added condition as well as to check if the exists is false or not if false then we're printing the not found statement.

Let's check the output

127.0.0.5 key not found 

Running Loop Over Map

The range form of the for loop is used to iterate over all elements of a map.


    
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        fmt.Println("Content of the usersVisited Map")
        for key, value := range usersVisited {
            fmt.Printf("userVisited[%s] = %d\n", key, value)
        }
    }




Output of the above code

Content of the usersVisited Map
userVisited[127.0.0.1] = 1
userVisited[127.0.0.2] = 2
userVisited[127.0.0.3] = 3
userVisited[127.0.0.4] = 4

Note :- One important fact is that the order of the retrieval of values from a map when using for range is not guaranteed to be the same for each execution of the program. It is also not the same as the order in which the elements were added to the map


Updating Value of a Key in Map

There is one more things which is more important you can update the values of any key at anytime in a map.

Let's try to update the value of 127.0.0.1 IP  from 1 to 2.


    
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        ip := "127.0.0.1"

        _, exists := usersVisited[ip]
        if !exists {
            userVisited[ip] = 1
        }
        usersVisited[ip]++

        fmt.Printf("IP %s\n%d Times Visited", ip, usersVisited[ip])
    }




So we have followed the same step for this as well as.
First we have checked for the key if key is not exists then we are adding new entry in our usersVisited map other wise increasing the count of our value for that ip address(Key).

Let's Check Output

IP 127.0.0.1
2 Times Visited

Deleting Entries From a Map

delete(map, key) is the syntax to delete key from a map. The delete function does not return any value.


 
    package main

    import "fmt"

    func main() {
        usersVisited := map[string]int{
            "127.0.0.1": 1,
            "127.0.0.2": 2,
            "127.0.0.3": 3,
            "127.0.0.4": 4,
        }

        fmt.Println("map before deleting entry", usersVisited)
        delete(usersVisited, "127.0.0.1")
        fmt.Println("map after deleting entry", usersVisited)
    }




The above program deletes the key(ip address) 127.0.0.1 from the map

Let's check the output

map before deleting entry map[127.0.0.1:1 127.0.0.2:2 127.0.0.3:3 127.0.0.4:4]
map after deleting entry map[127.0.0.2:2 127.0.0.3:3 127.0.0.4:4]




THANKS FOR READING





Labels:

0 Comments:

Post a Comment

If have any queries lemme know

Subscribe to Post Comments [Atom]

<< Home