goslicego-map

Transform a golang map into another structure of map


I need help for transforming this input map into the output map. I try with switch/case and for but I didn't succeed it. Thanks a lot !

Input :

Values{
                    "toto_voiture_brand": Ad{
                        "CITROEN": "CITROEN",
                    },
                    "toto_voiture_model": Ad{
                        "CITROEN_toto": "C3",
                    },
                    "toto_moto_brand": Ad{
                        "KAWASAKI": "KAWASAKI",
                    },
                    "toto_moto_model": Ad{
                        "KAWASAKI_tata": "Ninja 1000 SX",
                    },
                    "toto_camion_brand": Ad{
                        "RENAULT": "RENAULT",
                        "PEUGEOT": "PEUGEOT",
                    },
                    "toto_camion_model": Ad{
                        "RENAULT_toto":  "J5",
                        "PEUGEOT_tata": "255",
                    },
                },
            }

Output

Values{
                "toto_voiture_model": {
                    "Citroen": {
                        {Value: "C3"},
                    },
                },
                "toto_moto_model": {
                    "Kawasaki": {
                        {Value: "Ninja 1000 SX"},
                    },
                },
                "toto_camion_model": {
                    "RENAULT": {
                        {Value: "J5"},
                    },
                    "PEUGEOT": {
                        {Value: "255"},
                    },
                },
            }

I've tried with switch case and loop for and map. But I don't have the result attendee, I didn't found how to match every map, key and value. Thanks a lot


Solution

  • I should have managed what you need with the following code:

    package main
    
    import (
        "encoding/json"
        "fmt"
        "strings"
    )
    
    type Output struct {
        Value string `json:"Value"`
    }
    
    func main() {
        // declare output
        output := make(map[string]map[string]Output, 0)
        // input
        input := make(map[string]map[string]string, 0)
        input["toto_voiture_brand"] = map[string]string{
            "CITROEN": "CITROEN",
        }
        input["toto_voiture_model"] = map[string]string{
            "CITROEN_toto": "C3",
        }
        input["toto_moto_model"] = map[string]string{
            "KAWASAKI_tata": "Ninja 1000 SX",
        }
        input["toto_camion_model"] = map[string]string{
            "RENAULT_toto": "J5",
            "PEUGEOT_tata": "255",
        }
    
        // transformation
        for k, v := range input {
            if strings.HasSuffix(k, "_model") {
                tempMap := make(map[string]Output, len(v))
                for kk, vv := range v {
                    key := strings.Split(kk, "_")[0]
                    tempMap[key] = Output{
                        Value: vv,
                    }
                }
                output[k] = tempMap
            }
        }
    
        data, _ := json.MarshalIndent(&output, "", "\t")
        fmt.Println(string(data))
    }
    

    I put some comments within the code just to separate sections. The first two parts are only supposed to define your input and output variables.
    The section starting with // transformation is a good candidate to become a function but I preferred to leave it within the main function for demo purposes. Let me recap what's happens in the loop:

    1. You range over the entries of your input variable
    2. If the key has the suffix _model, you take it into consideration
    3. You define a locally-scoped map (called tempMap) of type map[string]Output with the right number of elements that we're gonna add
    4. You range over the v variable (that's why we're dealing with nested maps)
    5. For each item, you're gonna add an entry to the tempMap
    6. At the end of the nested loop, you add an entry to the parent map (output)

    The last part is only for printing a beautiful JSON that can be easily read and checked.

    Note that this code is simplified just to show off how to achieve your goal, adjust it before putting it into production.

    Let me know if this helps, thanks!