Go By Examples - Map types Advanced Programs


This post covers  Golang Map types tutorials with examples

In my previous post, Covered Map guide in Golang

Following are the  Map type  examples in Go Language

Sort a Map by key or values

The map is ordered data structure of key-value pairs. To sort map, We have to write a custom to handle this, For example, we have a map of string key and int values. Printing the map returns map data in random order, the order is not guaranteed.

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]  

We will see the map sort based on key order

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 25000  

Create a Nested Map type with an array of maps 

 In this example, you can create a Map with key as strings and value as Array of Maps First Create a Map with an array of maps using make a function of literal syntax

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

This creates a Map with the key is string assigned with a value of an array of maps Adding and deleting element work the same way like a normal maps Complete example of 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 is

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  

Convert Slice/Array to from Map 

 Slice is a dynamic array and its length grows at runtime. The map is a collection with key and value pairs. The map is good in performance for search, add and delete, but not good for Iteration There are no standard API functions to convert String to Map Sometimes we need to convert Slice string Declared and initialize 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 is integer and value is string Iterate slice either simple for loop or for 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 is

[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 changes.

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 talks about below things

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

Here is an example for Convert Map to Key/values/items Slices

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 is

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 single Map 

There is no standard function to merge or join the maps. We have to write a custom to merge multiple maps into a single map. Result Map might have multiple values for 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 source map to slice for the given key of output map¬†
  • once slice map is appended, we have to assign this slice to output map for given key¬†
  • This process allows duplicates elements in the output map¬†

here is complete example 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, keys, and values using Standard Reflection API reflect.TypeOf() function returns 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 panic error if given type is not map Herea is 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 is

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 

We have declared a struct with each element of the standard object of strings except Address element. Address element is of 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 conver 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 is

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

Similar Posts