在Go上将两个结构分组为第三个结构的最佳方法

时间:2019-10-21 17:29:14

标签: json loops go struct

我具有以下结构:

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
}

,我需要创建一个C1类型的[]结构,该结构包含一个B1Set B1,B1的数量超过2K,而A1的数量仅为10,这是一个非常缓慢且效率低下的实现,它会遍历A1,并询问B1-key是否等于A1-key并将结果存储在地图中,但是..有没有更好的方法来实现这一点?

预先感谢

添加更多信息:

它们是两个不同的JSON文件:

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

另一个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"
  },
  ...
]

所以我需要使用以下两个代码创建一个新的JSON文件:

[
  {
    "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"
         }
     ]
  }
]

考虑到Json1条目不超过10-12个,而Json2条目不超过800-1000个。

到目前为止:

读取Json1(设备)和Json2(端口),并将它们传递到两个[]结构中。然后:

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)
}

1 个答案:

答案 0 :(得分:0)

这是您要做什么? https://play.golang.org/p/AZNzQAwRhN0

这是建立一个按池将所有端口分组的映射。然后,它循环遍历我标记为clusters的内容,并通过Port值来获取匹配的切片,从而将Cluster的切片分配给匹配的Pool

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"
  }]`
)