Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge two or more []map[string]interface{} types into one in Golang

I'm using Golang and for some reason, I need to merge results from different database queries, all of which return me a []map[string]interface{} I'm thinking of Append but its just not clear enough if this is even possible. What is the final datatype I'm looking at?

Clearly, an array of maps of interfaces with keys as strings should be able to simply 'attach' (concat, if you may) to another array of maps of interfaces with keys as strings!

So what is the mechanism to achieve this?

like image 635
Gaurav Ojha Avatar asked Sep 08 '16 12:09

Gaurav Ojha


People also ask

What does map string interface{} mean?

map[string]interface{} is a map whose keys are strings and values are any type.

What is map string interface Golang?

It's map[string]interface{} all the way down! Configuration files, too, generally have this kind of schema. You can think of YAML or CUE files as being maps of string to empty interface, just like JSON. So when we're dealing with structured data of any kind, we'll often use this type in Go programs.

How do I create a string string map in Golang?

Create a map in Golang[string] - indicates that keys of the map are of string type. float32 - indicates that values of the map are of float type. {Golang", "Java", "Python"} - keys of the map. {85, 80, 81} - values of the map.

When to use map string interface?

When to use map[string]interface{}? The “map of string to empty interface” type is very useful when we need to deal with data; arbitrary JSON data(the data in any format)of an unknown schema.


2 Answers

Even the answer is already given in the comments above i will post a short example how this can be achieved.

package main

import (
    "fmt"
)

func main() {
    result := []map[string]interface{}{}

    mp1 := map[string]interface{}{
        "one" : 1, 
        "two" : 2,
    }

    mp2 := map[string]interface{}{
        "three" : 3,
        "four" : 4,
    }

    mp3 := make(map[string]interface{})
    for k, v := range mp1 {
        if _, ok := mp1[k]; ok {
            mp3[k] = v          
        }
    }

    for k, v := range mp2 {
        if _, ok := mp2[k]; ok {
            mp3[k] = v
        }
    }

    result = append(result, mp1, mp2)
    fmt.Println(result)
}

The output will be:

[map[one:1 two:2] map[three:3 four:4]]

Playground example

like image 130
Endre Simo Avatar answered Sep 20 '22 14:09

Endre Simo


The other answer is correct. You could also write a helper function to avoid repetitive map merges.

// overwriting duplicate keys, you should handle that if there is a need
func mergeMaps(maps ...map[string]interface{}) map[string]interface{} {
    result := make(map[string]interface{})
    for _, m := range maps {
        for k, v := range m {
            result[k] = v
        }
    }
    return result
}

func main() {
    log.Println(`started`)

    v := []map[string]interface{}{
        map[string]interface{}{
            `one`: 1,
            `two`: 2,
        },
        map[string]interface{}{
            `one`:   `I`,
            `three`: 3,
            `other`: `NAN`,
        },
        map[string]interface{}{
            `name`: `Bob`,
            `age`:  300,
        },
    }

    m := mergeMaps(v...)
    log.Println(m, len(m))
}
like image 26
Kaveh Shahbazian Avatar answered Sep 20 '22 14:09

Kaveh Shahbazian