Сопоставить данные из структурных объектов - PullRequest
0 голосов
/ 04 сентября 2018

в следующем коде (который я повторно использовал из предыдущего вопроса) нам нужно сопоставить объекты в соответствии с соответствующими ключами значениями

Ключи имеют значение

от модели internalConfig

Тип

Из внешнего конфига

приложение типа

В случае, если у нас есть 'match' (в значении), нам нужно заменить данные из внешнего конфига и обновить внутренний конфиг

* 1025 например *. если для zone2 app-type = app1 равен внутреннему типу конфигурации = app1, нам нужно изменить содержимое внешнего конфига на

от

- name: TEST
  type: app1
  target: ./

в (поскольку 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

Если вам нужно больше разъяснений, пожалуйста, дайте мне знать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...