duanbogan5878 2019-04-12 19:30
浏览 87

如何通过遍历JSON在golang中显示缺少的键?

I am building a translation tool for my app. I have 2 different json files (en.json, fr.json), where my keys and values are.

The en.json file is the referent file which means the keys present in this file need to be added in the fr.json file if they do not exist . For more details, if the key is present in the en.json and not in the fr.json we need to display but if the key is only present in the fr.json, it does not count and we display nothing on the screen. And if the key is already present in both of them we don’t need to display something on the screen.

The en.json file is the referent file with the following keys :

  {
  "i18n-outterJSON": {
        "i18n-value1": "value1",
        "i18n-value2": "value2",
        "i18n-dad" : "dady"
    },
    "InnerJSON2":"NoneValue",
    "hello" : "good morning",
    "onlykey" : "only key",
    "secondekey" : "second key",
    "mother": {
      "daugther": "fille"
    }

}

The fr.json file is the Target file. With the following keys:

    {
  "i18n-outterJSON": {
    "i18n-value1": "value1",
    "i18n-value2": "value2"
  },
  "i18n-hello" : "bonjour",
  "i18n-variation" : "variation",
  "alouette" : "cacahouete",
  "InnerJSON2":"pas de valeur",
  "hello" : "bonjour"
}

My code in golang is :

fileEnglish := GetAllPathRefFile(); // to open the reference file
  files := GetAllI18nFiles(); // to open the french file

  for _, fileRef := range fileEnglish {
    mapRef := ReadJsonFile(constants.PathRefFile + GetRidOfExtension(fileRef.Name()))

    for _, fileTarget := range files {
      mapTarget := ReadJsonFile(constants.I18nPath + GetRidOfExtension(fileTarget.Name()));
      mapTarget = MissingKey(mapRef, mapTarget)



      // range loop to identify the missing keys in the different files
      for key, _ := range mapRef { // mapRef is the reference map of the reference file en.json
        if  mapRef[key] != mapTarget[key]  { // mapTarget is map of the target file fr.json
          t := strings.Replace(key, key, "", -1)
            _ = t
            fmt.Println("the missing keys are: ", key)
            }
          }
        }
      }

I tried to compare each key and in some cases we have a hierarchy and I tried to identify the missing keys. I need to obtain this result :

i18n-dad
mother
daughter
onlykey
secondekey

But with my current code I have this error : comparing uncomparable type map[string]interface {}.

How can we identify and print on the screen correctly the keys?

  • 写回答

1条回答 默认 最新

  • dongqiao6445 2019-04-12 20:48
    关注

    Here is a quick example to show what is missing in the French JSON by using https://github.com/go-test/deep.

    package main
    
    import (
        "encoding/json"
        "fmt"
        "strings"
    
        "github.com/go-test/deep"
    )
    
    type Data struct {
        I18NOutterJSON struct {
            I18NValue1 string `json:"i18n-value1"`
            I18NValue2 string `json:"i18n-value2"`
            I18NDad    string `json:"i18n-dad"`
        } `json:"i18n-outterJSON"`
        InnerJSON2 string `json:"InnerJSON2"`
        Hello      string `json:"hello"`
        Onlykey    string `json:"onlykey"`
        Secondekey string `json:"secondekey"`
        Mother     struct {
            Daugther string `json:"daugther"`
        } `json:"mother"`
    }
    
    func main() {
        enJSON := []byte(`{"i18n-outterJSON":{"i18n-value1":"value1","i18n-value2":"value2","i18n-dad":"dady"},"InnerJSON2":"NoneValue","hello":"good morning","onlykey":"only key","secondekey":"second key","mother":{"daugther":"fille"}}`)
        frJSON := []byte(`{"i18n-outterJSON":{"i18n-value1":"value1","i18n-value2":"value2"},"i18n-hello":"bonjour","i18n-variation":"variation","alouette":"cacahouete","InnerJSON2":"pas de valeur","hello":"bonjour"}`)
    
        var en, fr Data
        err := json.Unmarshal(enJSON, &en)
        if err != nil {
            panic(err)
        }
    
        err = json.Unmarshal(frJSON, &fr)
        if err != nil {
            panic(err)
        }
    
        diff := deep.Equal(en, fr)
        for _, d := range diff {
            if strings.HasSuffix(d, "!= ") {
                fmt.Printf("%s
    ", d)
            }
        }
    }
    
    
    $ go run .
    I18NOutterJSON.I18NDad: dady != 
    Onlykey: only key != 
    Secondekey: second key != 
    Mother.Daugther: fille != 
    

    Edit based on comment. Adding a way to use arbitrary JSON instead of a struct.

    func withArbitraryJSON(enJSON []byte, frJSON []byte) {
        var en map[string]interface{}
        err := json.Unmarshal(enJSON, &en)
        if err != nil {
            panic(err)
        }
    
        var fr map[string]interface{}
        err = json.Unmarshal(frJSON, &fr)
        if err != nil {
            panic(err)
        }
    
        diff := deep.Equal(en, fr)
        for _, d := range diff {
            if strings.HasSuffix(d, "!= <does not have key>") {
                fmt.Printf("%s
    ", d)
            }
        }
    }
    

    Output:

    $ go run .
    map[i18n-outterJSON].map[i18n-dad]: dady != <does not have key>
    map[onlykey]: only key != <does not have key>
    map[secondekey]: second key != <does not have key>
    map[mother]: map[daugther:fille] != <does not have key>
    
    评论

报告相同问题?

悬赏问题

  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试