Home > Net >  Creating a new slice from an array of objects golang and group
Creating a new slice from an array of objects golang and group

Time:06-06

I have an array of objects that I would like to use to create a new slice while grouping a field for objects with the same id(the id, in this case, the id is pay_method_id) into an array of objects. i.e I want to group all users with a particular payment method

sample input

[{
    "user_id": 1,
    "pay_method_id": 1
}

{
    "user_id": 2,
    "pay_method_id": 2
}

{
    "user_id": 4,
    "pay_method_id": 1
}

{
    "user_id": 3,
    "pay_method_id": 2
}]

expected output

[
    {"pay_method_id" : "2",
     "users": [{"user_id": 2}, {"user_id": 3}]
    
    }
    {
        "pay_method_id" : "1",
        "users": [{"user_id": 4}, {"user_id": 1}]
       
       }
]

Struct representing input

type paymenthodUsers struct{
   PayMethodID int
   UserID int
}

Struct for the output

type paymentMethodGrouped struct{
   PayMethodID int
   Users []user
}
type user struct{
   UserID int
}

How do I generate the expected output above in golang?

CodePudding user response:

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type paymenthodUsers struct {
    PayMethodID int `json:"pay_method_id"`
    UserID      int `json:"user_id"`
}

type paymentMethodGrouped struct {
    PayMethodID int    `json:"pay_method_id"`
    Users       []user `json:"users"`
}
type user struct {
    UserID int `json:"user_id"`
}

func main() {
    _json := `[{
    "user_id": 1,
    "pay_method_id": 1
    },

    {
    "user_id": 2,
    "pay_method_id": 2
    },

    {
    "user_id": 4,
    "pay_method_id": 1
    },

    {
    "user_id": 3,
    "pay_method_id": 2
    }]`
    var paymentmethods []paymenthodUsers
    err := json.Unmarshal([]byte(_json), &paymentmethods)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Original input : % v\n", paymentmethods)
    groups := make(map[int][]user)
    for _, pm := range paymentmethods {
        if _, found := groups[pm.PayMethodID]; !found {
            groups[pm.PayMethodID] = []user{}
        }
        groups[pm.PayMethodID] = append(groups[pm.PayMethodID], user{pm.UserID})
    }
    paymentGroups := []paymentMethodGrouped{}
    for k, v := range groups {
        paymentGroups = append(paymentGroups, paymentMethodGrouped{k, v})
    }
    data, err := json.Marshal(paymentGroups)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Grouped: %s", string(data))
}

Go Playground Demo

  •  Tags:  
  • go
  • Related