匹配来自结构对象的数据

时间:2018-09-04 07:29:35

标签: go struct

在以下代码(我从上一个问题中重复使用)中,我们需要根据匹配的

来匹配对象
  

键是的值

来自模型internalConfig

类型

通过外部配置

应用类型

如果“匹配”(值),我们需要替换外部配置中的数据并更新内部配置

例如。如果对于zone2 app-type = app1等于内部配置type = app1,我们需要将外部配置的内容更改为

来自

- name: TEST
  type: app1
  target: ./

to(因为app1在内部和外部配置中均相等-我们正在将数据从外部更新为内部)

- name: TEST
  type: AZURE 
  target: ./

鉴于上述数据,内部配置应在匹配后照看

最后应该看起来像

- name: TEST
  type: AZURE 
  target: ./

- name: TEST3
  type: HEROKU
  target: ./

- name: TEST2
  type: app3
  target: ./

- name: TEST2
  type: AZURE 
  target: ./

我正在尝试以下操作,但是如果同一键只有一个以上的条目,则我无法匹配所有对象 例如app1“键”位于第一个和最后一个条目中,因此我的代码仅更新了第一个条目

- name: TEST
  type: app1
  target: ./

- name: TEST3
  type: app2
  target: ./

- name: TEST2
  type: app3
  target: ./

- name: TEST2
  type: app1
  target: ./

任何想法我该如何解决?这是我尝试过的方法,仅在第一个比赛中有效

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
    "log"
)


type InternalConfig struct {
    Models []Imodel `yaml:"models"`
}

type Imodel struct {
    Name   string `yaml:"name"`
    Type   string `yaml:"type"`
    Target string `yaml:"target"`
}

var internalConfig = []byte(`
models:
   - name: TEST
     type: app1
     target: ./

   - name: TEST3
     type: app2
     target: ./

   - name: TEST2
     type: app3
     target: ./

   - name: TEST2
     type: app1
     target: ./
`)

type ExternalConfig struct {
    Landscape Zone `yaml:"Landscape"`
}

type Zone struct {
    Zone   string   `yaml:"zone"`
    Models []Emodel `yaml:"models"`
}

type Emodel struct {
    AppType     string `yaml:"app-type"`
    ServiceType string `yaml:"service-type"`
}

var externalConfig = []byte(`
Landscape:
  zone: zone1
  models:
    - app-type: app1
      service-type: GCP
    - app-type: app2
      service-type: AMAZON
  zone: zone2
  models:
    - app-type: app1
      service-type: AZURE
    - app-type: app2
      service-type: HEROKU
`)

func main() {
    iCfgYaml := InternalConfig{}
    if err := yaml.Unmarshal(internalConfig, &iCfgYaml); err != nil {
        log.Fatalf("error in model InternalConfig: %v", err)
    }

    eCfgYaml := ExternalConfig{}
    if err := yaml.Unmarshal(externalConfig, &eCfgYaml); err != nil {
        log.Fatalf("error in model ExternalConfig: %v", err)
    }
    if err := UpdateInternalState(&iCfgYaml, eCfgYaml, "zone2"); err != nil {
        log.Fatalf("Error updating internal config: %v", err)
    }
    fmt.Printf("DBG: %+v\n", iCfgYaml)
}

func UpdateInternalState(iCfg *InternalConfig, eCfg ExternalConfig, zone string) error {
    ilm := make(map[string]int)
    for i, v := range iCfg.Models {
        ilm[v.Type] = i
    }
    for _, em := range eCfg.Landscape.Models {
        if eCfg.Landscape.Zone == zone {

            if i, ok := ilm[em.AppType]; ok {
                iCfg.Models[i].Type = em.ServiceType
            }
        }
    }
    return nil
}

如果您运行上面的代码,这就是您将获得的数据

{Models:[
{Name:TEST Type:app1 Target:./} 
{Name:TEST3 Type:HEROKU Target:./} 
{Name:TEST2 Type:app3 Target:./} 
{Name:TEST2 Type:AZURE Target:./}]}

第一个条目未更新

https://play.golang.org/p/5f3Ad9Z7fqY

如果需要更多说明,请告诉我

0 个答案:

没有答案