I don't think there is an easy way to do this.
The following uses a custom unmarshaller, a custom type, and finally a sorting routine to do the job. You could also do the job within the unmarshaller if you used []Product
as the type to unmarshal, but the following is effective.
package main
import (
"encoding/json"
"fmt"
"os"
"sort"
)
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Dimension []Dimensions `json:"dimensions"`
}
type Dimensions struct {
Length int `json:"length"`
Width int `json:"width"`
Height int `json:"height"`
}
var stuff = `[
{"id":1,"name":"abc","length":1,"width":2,"height":3},
{"id":1,"name":"abc","length":4,"width":5,"height":6},
{"id":2,"name":"pqr","length":4,"width":5,"height":6},
{"id":3,"name":"xyz","length":1,"width":2,"height":3},
{"id":3,"name":"xyz","length":4,"width":5,"height":6},
{"id":3,"name":"xyz","length":7,"width":8,"height":9}
]`
type PseudoProduct struct {
ID int `json:"id"`
Name string `json:"name"`
}
func (p *Product) UnmarshalJSON(j []byte) (err error) {
var d Dimensions
err = json.Unmarshal(j, &d)
if err != nil {
return err
}
var q PseudoProduct
err = json.Unmarshal(j, &q)
if err != nil {
return err
}
p.Name = q.Name
p.ID = q.ID
p.Dimension = append(p.Dimension, d)
return nil
}
type ProdList []Product
func (pl ProdList) Len() int {
return len(pl)
}
func (pl ProdList) Less(i, j int) bool {
pi := pl[i]
pj := pl[j]
return pi.ID < pj.ID || pi.Name < pj.Name
}
func (pl ProdList) Swap(i, j int) {
pl[i], pl[j] = pl[j], pl[i]
}
func main() {
var products []Product
err := json.Unmarshal([]byte(stuff), &products)
if err != nil {
fmt.Fprintf(os.Stderr, "Error unmarshalling: %s\n", err)
os.Exit(1)
}
sort.Sort(ProdList(products))
n := len(products)
newproducts := make([]Product, 0)
for i := 0; i < n; i++ {
pi := products[i]
for j := i + 1; j < n; j++ {
pj := products[j]
if pj.ID != pi.ID || pj.Name != pi.Name {
break
}
pi.Dimension = append(pi.Dimension, pj.Dimension[0])
i++
}
newproducts = append(newproducts, pi)
}
fmt.Printf("%v\n", newproducts)
}
Playground: https://go.dev/play/p/Sv-5dtVmBlw
sqlx
tag and mentionsStructScan
so I'm quite certain this has nothing to do with JSON unmarshaling. – mkopriva