Convert map to struct in Golang [4 Methods]

Convert map to struct in Golang [4 Methods]

Different methods to convert map to struct in GO

In Golang, a struct is a collection of fields, and a map is a collection of key-value pairs. The process of converting a map to a struct involves creating a new struct and setting its fields to the corresponding values in the map. We can achieve this using different methods, some of them are as below:

  • Using for loop
  • Using reflect package
  • Using json.Unmarshal() function
  • Using mapstructure library

Method-1: Using json.Unmarshal() function

This method converts a JSON-formatted byte slice to a struct using the json.Unmarshal() function.

package main

import (
    "encoding/json"
    "fmt"
)

type MyStruct struct {
    Name    string `json:"name"`
    Age     int    `json:"age"`
    Address string `json:"address"`
}

func main() {
    // Define the map
    map1 := map[string]interface{}{
        "name":    "Amit Kumar",
        "age":     30,
        "address": "316 Some Main Road, Cruasia",
    }

    // Convert the map to JSON
    jsonData, _ := json.Marshal(map1)

    // Convert the JSON to a struct
    var structData MyStruct
    json.Unmarshal(jsonData, &structData)

    fmt.Println(structData) // {Amit Kumar 30 316 Some Main Road, Cruasia}
}

Method-2: Using mapstructure library

The mapstructure library provides a way to convert a map to a struct using struct tags. It also provides additional functionality such as type conversion, default values, and validation.

package main

import (
    "fmt"

    "github.com/mitchellh/mapstructure"
)

type MyStruct struct {
    Name    string
    Age     int
    Address map[string]string
}

func main() {
    // Define the map
    map1 := map[string]interface{}{
        "name": "Amit Kumar",
        "age":  30,
        "address": map[string]string{
            "street": "316 Some Main Road",
            "city":   "Crusasia",
            "state":  "Karnataka",
            "zip":    "803471",
        },
    }

    // Create a new struct to hold the data
    var data MyStruct

    // Use mapstructure to map the data from the map to the struct
    config := &mapstructure.DecoderConfig{
        ErrorUnused: true,
        Result:      &data,
    }
    decoder, err := mapstructure.NewDecoder(config)
    if err != nil {
        fmt.Println(err)
        return
    }
    if err := decoder.Decode(map1); err != nil {
        fmt.Println(err)
        return
    }

    // Print the struct data
    // {Name:Amit Kumar Age:30 Address:map[city:Crusasia state:Karnataka street:316 Some Main Road zip:803471]}
    fmt.Printf("%+v", data)
}

Method-3: Using simple for loop

Here is an example where we use a simple for loop to loop through the map element and convert it into a struct:

package main

import "fmt"

type Identity struct {
    Name string
    Age  int
}

func main() {
    m := map[string]interface{}{
        "Name": "Amit Kumar",
        "Age":  30,
    }

    var p Identity
    for k, v := range m {
        switch k {
        case "Name":
            p.Name = v.(string)
        case "Age":
            p.Age = v.(int)
        }
    }

    // {Name:Amit Kumar Age:30}
    fmt.Printf("%+v\n", p)
}

Method-4: Using reflect package

The reflect package provides functions for inspecting the type and value of Go objects at runtime. So we can also use this package, here is an example:

package main

import (
    "fmt"
    "reflect"
)

type Identity struct {
    Name string
    Age  int
}

func convertMapToStruct(m map[string]interface{}, s interface{}) error {
    stValue := reflect.ValueOf(s).Elem()
    sType := stValue.Type()
    for i := 0; i < sType.NumField(); i++ {
        field := sType.Field(i)
        if value, ok := m[field.Name]; ok {
            stValue.Field(i).Set(reflect.ValueOf(value))
        }
    }
    return nil
}

func main() {
    m := map[string]interface{}{
        "Name": "Amit Kumar",
        "Age":  30,
    }

    var p Identity
    err := convertMapToStruct(m, &p)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("%+v\n", p) // {Name:Amit Kumar Age:30}
}

In this example, we define a function convertMapToStruct that takes a map and a struct pointer as arguments. Inside the function, we use the reflect package to get the value and type of the struct inside stValue and sType respectively. Then we use a for loop to iterate over the struct fields and check if the field name exists in the map. If it does, we use the reflect package to set the struct field value to the corresponding map value.


Summary

In this tutorial we covered different possible methods to convert map to struct with examples. The methods we explored are using for loop, reflect package, mapstructure library, json.Unmarshal() package. There are many other possible ways such as we can also use struct tags, or we can manually do the mapping unless the map is complex.

So let us know your views in the comments section.

Deepak Prasad

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.