json – Best way to group two structs into a third one on Go-ThrowExceptions

Exception or error:

I have the following structs:

type A1 struct {
   IdA1 string
   NameA1 string
   key string
}

type B1 struct {
   IdB1 string
   NameB1 string
   Size string
   key string
}

type C1 struct {
   IdA1 string
   Name string
   B1Set B1
}

and I need to create a []struct of type C1, that holds a B1Set of B1, B1 is huge more than 2K entries and A1 is just 10 entries, a really slow and inefficient implementation would be to loop over A1, and ask if B1-key is equal to A1-key and store in a map the result, but.. is there any better way to implement this?

thanks in advance,

Add more info:

They are two different JSON files:

Json1:
[
  {
    "id": "device1",
    "name": "dev1",
    "pool": "pool1"
  },
  {
    "id": "device2",
    "name": "dev2",
    "pool": "pool2"
  }
  ...
]

And the other Json:

[
  {
    "name": "port1",
    "size": 10,
    "pool": "pool1",
    "status": "active"
  },
  {
    "name": "port2",
    "size": 60,
    "pool": "pool1",
    "status": "active"
  },
  {
    "name": "port3",
    "size": 20,
    "pool": "pool2",
    "status": "down"
  },
  {
    "name": "port8",
    "size": 100,
    "pool": "pool2",
    "status": "active"
  },
  {
    "name": "port10",
    "size": 8000,
    "pool": "pool1",
    "status": "active"
  },
  ...
]

So I need to create a new JSON file from those two with the following:

[
  {
    "id": "device1",
    "name": "dev1",
    "pool": "pool1",
    "ports": [
         {
           "name": "port1",
           "size": 10,
           "pool": "pool1",
           "status": "active"
         },
         {
           "name": "port2",
           "size": 60,
           "pool": "pool1",
           "status": "active"
         },
         {
           "name": "port10",
           "size": 8000,
           "pool": "pool1",
           "status": "active"
         }
     ]
  },
  {
    "id": "device2",
    "name": "dev2",
    "pool": "pool2",
    "ports": [
         {
           "name": "port3",
           "size": 20,
           "pool": "pool2",
           "status": "active"
         },
         {
           "name": "port8",
           "size": 100,
           "pool": "pool2",
           "status": "active"
         }
     ]
  }
]

taking into account that Json1 is not more than 10-12 entries and Json2 has more than 800-1000 entries.

So far:

read Json1 (devices), and Json2 (ports) and pass them into two []structs. Then:

results := make(map[string]*models.PortDevices}
portDevs := []models.PortDevices{}

for i := range devices {
   results[devices[i].Pool] = &models.PortDevices{}
   m := results[devices[i].Pool]
   m.Id = devices[i].Id
   m.Name = devices[i].Name
   m.Pool = devices[i].Pool
   m.Status = devices[i].Status
   for p := range ports {
      if val, ok := results[ports[p].Pool]; ok {
         m := val
         m.Ports = ports
      }
   }

   portDevs = append(portDevs, *m)
}

devports := []models.PortDevices{}

for _, value := range results {
   devports = append(devports, *value)
}
How to solve:

Is this what you are looking to do? https://play.golang.org/p/AZNzQAwRhN0

What this does is build a map grouping all of the ports by pool. Then it loops through what I labeled clusters and assigns the slice of Port to the matching Cluster by grabbing the matching slice by Pool value.

package main

import (
    "encoding/json"
    "fmt"
)

type Cluster struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Pool  string `json:"pool"`
    Ports []Port `json:"ports"`
}

type Port struct {
    Name   string `json:"name"`
    Size   int    `json:"size"`
    Pool   string `json:"pool"`
    Status string `json:"status"`
}

func main() {
    var resources []Port
    err := json.Unmarshal([]byte(resourceJSON), &resources)
    if err != nil {
        panic(err)
    }
    resourcesByPool := make(map[string][]Port)
    for _, resource := range resources {
        if _, ok := resourcesByPool[resource.Pool]; !ok {
            resourcesByPool[resource.Pool] = []Port{}
        }
        resourcesByPool[resource.Pool] = append(resourcesByPool[resource.Pool], resource)
    }

    var clusters []Cluster
    err = json.Unmarshal([]byte(clusterJSON), &clusters)
    if err != nil {
        panic(err)
    }
    for i := 0; i < len(clusters); i++ {
        clusters[i].Ports = resourcesByPool[clusters[i].Pool]
    }

    out, err := json.MarshalIndent(clusters, "", "    ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(out))

}

var (
    clusterJSON = `[
  {
    "id": "device1",
    "name": "dev1",
    "pool": "pool1"
  },
  {
    "id": "device2",
    "name": "dev2",
    "pool": "pool2"
  }
]`

    resourceJSON = `[
  {
    "name": "port1",
    "size": 10,
    "pool": "pool1",
    "status": "active"
  },
  {
    "name": "port2",
    "size": 60,
    "pool": "pool1",
    "status": "active"
  },
  {
    "name": "port3",
    "size": 20,
    "pool": "pool2",
    "status": "down"
  },
  {
    "name": "port8",
    "size": 100,
    "pool": "pool2",
    "status": "active"
  },
  {
    "name": "port10",
    "size": 8000,
    "pool": "pool1",
    "status": "active"
  }]`
)

Leave a Reply

Your email address will not be published. Required fields are marked *