Golang Map Example - Frequently Used programs

This post covers Golang Map types tutorials with examples

In my previous post, Learned Golang Map Tutorials.

Let’s see Map type examples in Go Language.

How to Sort a Map by key or values in Golang?

The map is an ordered data structure with key-value pairs in Golang.

We have to write a custom code to sort maps,

For example, we have a map of string key and int values.

Printing the map returns map data in random order and the order is not guaranteed.

Here is Print the map example

package main

import (
 "fmt"
)
func main() {
 employees := map[string]int{"Kiran": 2030, "John": 10210,
  "Mark": 25000}
 fmt.Println(employees)
 fmt.Println(employees)
 fmt.Println(employees)
 fmt.Println(employees)
 fmt.Println(employees)
}

Output is

map[John:10210 Mark:25000 Kiran:2030]
map[John:10210 Mark:25000 Kiran:2030]
map[Kiran:2030 John:10210 Mark:25000]
map[Mark:25000 Kiran:2030 John:10210]
map[Kiran:2030 John:10210 Mark:25000]

Now, How do you sort maps based on Key values?

package main

import (
 "fmt"
 "sort"
)

func main() {
 employees := map[string]int{"Kiran": 2030, "John": 10210, "Mark": 25000}
 fmt.Println(employees)

 keys := make([]string, 0, len(employees))
 for k := range employees {
  keys = append(keys, k)
 }
 sort.Strings(keys)
 for _, k := range keys {
  fmt.Println(k, employees[k])
 }
}

The map is displayed with key ordered and Output is

map[Mark:25000 Kiran:2030 John:10210]
John 10210
Kiran 2030
Mark

How to Create a Nested Map type with an array of maps

In this example, Create a Map with keys as strings and values as an Array of Maps.

First, Create a Map with an array of maps using the function of literal syntax.

 mapArraysMap := map[string][]map[string]string{
  "kiran": {{"id": "1"}, {"name": "kiran"}},
  "john":  {{"id": "2"}, {"name": "kiran"}},
 }

It creates a Map with the key as a string, assigned with a value of an array of maps. Adding and deleting elements work the same way as normal maps.

Here is a complete example of a Map with an array of maps

package main

import (
 "fmt"
)

func main() {

 //Create a Map with array of map
 mapArraysMap := map[string][]map[string]string{
  "kiran": {{"id": "1"}, {"name": "kiran"}},
  "john":  {{"id": "2"}, {"name": "kiran"}},
 }
 fmt.Println(mapArraysMap)
 fmt.Println("Original length: ", len(mapArraysMap))
 //Adding an Array of Map values to map
 mapArraysMap["frank"] = []map[string]string{{"id": "2"}, {"name": "kiran"}}
 fmt.Println(mapArraysMap)
 fmt.Println("length: ", len(mapArraysMap))
 //Delete entry from Map
 delete(mapArraysMap, "frank")
 fmt.Println("length: ", len(mapArraysMap))

}

Output:

map[3:Gef 1:ram 2:arun]
map[kiran:[map[id:1] map[name:kiran]] john:[map[id:2] map[name:kiran]]]
Original length:  2
map[john:[map[id:2] map[name:kiran]] frank:[map[id:2] map[name:kiran]] kiran:[map[id:1] map[name:kiran]]]
length:  3
length:  2

How to Convert Slice/Array to from Map?

Slice is a dynamic array and its length grows at runtime. The map is a collection of key and value pairs.

The map is good in performance for search, add and delete, but not good for Iterations. Sometimes, we need to convert a Slice of strings into MAP. However, there are no standard API functions to convert Slice String to Map.

Declared and initialized a slice with string literals like below

//create a slice with string literal
countries := []string{"india", "USA", "UK", "France"}

And also create a Map with the key integer and the value is a string. Iterate slice with either simple for loop or loop with range.

Here is a complete example

package main

import (
 "fmt"
)

func main() {

 //create a slice with string literal
 countries := []string{"india", "USA", "UK", "France"}
 fmt.Println(countries)
 // Create and initilize a Map with make function
 countriesMap := make(map[int]string)
 // Iterate Slice
 for i := 0; i < len(countries); i++ {
  countriesMap[i] = countries[i]
 }
 fmt.Println(countriesMap)
}

Output:

[india USA UK France]
map[2:UK 3:France 0:india 1:USA]

Since Map is an unordered data structure, When you run the above program multiple times, the order of displayed data might change.

How to Convert Map to Key/value/ item Slice of arrays?

Often, we need to retrieve keys, values, or both from a Map type. For example, We have a Map with the key and values of string types. The Below program tells about the below things.

  • Slice of keys from Map.
  • An array of values from Map.
  • Key-value of item slices from Map.

Here is a code for Convert Map to Key/values/items Slices example.

package main

import (
 "fmt"
)

func main() {
 // Create and intilize map with string literals - First Name - Last Name
 names := map[string]string{
  "kiran":  "Babu",
  "John":   "Frank",
  "Silver": "Stallin",
 }
 fmt.Println("Map   ", names)
 fmt.Println("Key value ", names)

 // Retrieve keys of slice from Map
 keys := []string{}
 for key, _ := range names {
  keys = append(keys, key)
 }
 fmt.Println("Keys  ", keys)

 // Retrieve values of slice from Map
 values := []string{}
 for _, value := range names {
  values = append(values, value)
 }
 fmt.Println("Values ", values)

 // Retrieve  slice of key-value pairs from Map
 items := [][]string{}
 for key, value := range names {
  items = append(items, []string{key, value})
 }
 fmt.Println("Values ", items)

}

Output:

Map    map[kiran:Babu John:Frank Silver:Stallin]
Key value  map[Silver:Stallin kiran:Babu John:Frank]
Keys   [Silver kiran John]
Values  [Frank Stallin Babu]
Values  [[Silver Stallin] [kiran Babu] [John Frank]]

Merge Two or more maps into a single Map

There is no standard function to merge or join the maps in Golang. We have to write a custom to merge multiple maps into a single map.

Result Map might have multiple values for a given key, so the value should be declared as slice and then the output map of type map[string][]string.

Here is the map merge process

  • Iterate the maps
  • For each iteration, Append each value from the source map to slice for the given key of the output map
  • once the slice map is appended, we have to assign this slice to the output map for the given key
  • This process allows duplicated elements in the output map

Here is a complete example of map merge

package main

import (
 "fmt"
)

func main() {
 m1 := map[string]string{"k1": "v1"}
 m2 := map[string]string{"k2": "v2"}
 m3 := map[string]string{"k1": "v3"}

 output := mergeMaps(m1, m2, m3)
 fmt.Println(output)

}
func mergeMaps(maps ...map[string]string) map[string][]string {
 result := map[string][]string{}
 for _, m := range maps {
  for k, v := range m {
   result[k] = append(result[k], v)
  }
 }
 return res
}

The output of the above program

map[id_1:[val_1 val_3] id_2:[val_2]]

How to Check Type of Key and values of Map - Reflection API

We can get the type of map’s key, and value using Standard Reflection API.

reflect.TypeOf() functionreturns the dynamic type of given variable. It returns nil if given variable is nil interface.

reflect.TypeOf().key() function returns the map key data type. It throws a panic error if given type is not map type.

reflect.TypeOf().elem() function returns the map value data type. It throws a panic error if the given type is not map.

Here is a complete example

package main

import (
 "fmt"
 "reflect"
)

func main() {

 var mymap map[string]int
 fmt.Println("Map Type: ", reflect.TypeOf(mymap))
 fmt.Println("Map Key Type: ", reflect.TypeOf(mymap).Key())
 fmt.Println("Map Value Type: ", reflect.TypeOf(mymap).Elem())

 mapArraysMap := map[string][]map[string]string{
  "kiran": {{"id": "1"}, {"name": "kiran"}},
 }
 fmt.Println("Map Type: ", reflect.TypeOf(mapArraysMap))
 fmt.Println("Map Key Type: ", reflect.TypeOf(mapArraysMap).Key())
 fmt.Println("Map Value Type: ", reflect.TypeOf(mapArraysMap).Elem())

}

Output:

Map Type:  map[string]int
Map Key Type:  string
Map Value Type:  int
Map Type:  map[string][]map[string]string
Map Key Type:  string
Map Value Type:  []map[string]string

Convert Struct type with Map into JSON type

In the given code below, We have declared a struct with each element of the standard String object except the Address element. The address element is a map of strings.

type Employee struct {
 Id      string            `json:"id,omitempty"`
 Name    string            `json:"name,omitempty"`
 Address map[string]string `json:"address,omitempty"`
}

Will convert this struct to JSON using json.MarshalIndent() function

Following is an example

package main

import (
 "encoding/json"
 "fmt"
)

// Declare Struct type
type Employee struct {
 Id      string            `json:"id,omitempty"`
 Name    string            `json:"name,omitempty"`
 Address map[string]string `json:"address,omitempty"`
}

func main() {
 // Initialized Struct and add data to it
 var emp Employee
 emp.Id = "1"
 emp.Name = "Frank"
 m := make(map[string]string)
 emp.Address = m
 emp.Address["city"] = "Newyork"
 emp.Address["country"] = "USA"
 emp.Address["zipcode"] = "92451"

 var data []byte
 // Convert struct to json
 data, _ = json.MarshalIndent(emp, "", "    ")

 fmt.Println(string(data))
}

Output:

{
    "id": "1",
    "name": "Frank",
    "address": {
        "Country": "USA",
        "city": "Newyork",
        "zipcode": "92451"
    }
}

Summary

In this post, You learned golang map type with multiple examples and conversions from the map to slice and array and struct nested.