json - 在 go 模板中加入范围 block

标签 json loops dictionary go go-templates

我有一个像这样的 go 模板:

 "environment": [
   {{- range $k,$v := .env }}
     {
       "name": "{{ $k }}",
       "value": "{{ $v }}"
     },
   {{- end }}
   ]

我得到以下输出:

     "environment": [
    {
      "name": "name",
      "value": "test"
    },
    {
      "name": "region",
      "value": "us-east-1"
    },
  ]

我想像下面这样渲染它:

    "environment": [
    {
      "name": "name",
      "value": "bxbd"
    },
    {
      "name": "region",
      "value": "us-east-1"
    }
  ]

我无法摆脱最后一个逗号来制作有效的 json。 或者是否有可能以某种方式将完整的范围 block 发送到某个自定义连接函数?

最佳答案

这是一个如何使用模板来完成的示例,但如果您想生成 JSON,我强烈建议使用第二种方法。

坚持使用模板

由于您是在 map 上测距,因此您不能(简单地)这样做。对于 slice ,您可以检查索引变量(示例:Go template remove the last comma in range loop ;和 detect last item inside an array using range inside go-templates),但对于 map ,您不能这样做。

知道您是否处于第一次(或最后一次)迭代是您必须自己维护的状态。例如,为此使用自定义函数或方法。

这是一个示例实现:

type Params struct {
    Env     map[string]string
    Counter int
}

func (p *Params) IncMore() bool {
    p.Counter++
    return p.Counter < len(p.Env)
}

const src = `"environment": [
   {{- range $k,$v := .Env }}
     {
       "name": "{{ $k }}",
       "value": "{{ $v }}"
     }{{if $.IncMore}},{{end}}
   {{- end }}
   ]`

测试它:

func main() {
    t := template.Must(template.New("").Parse(src))
    p := &Params{
        Env: map[string]string{
            "name":   "test",
            "region": "us-east-1",
        },
    }
    err := t.Execute(os.Stdout, p)
    if err != nil {
        panic(err)
    }
}

输出(在 Go Playground 上尝试):

"environment": [
     {
       "name": "name",
       "value": "test"
     },
     {
       "name": "region",
       "value": "us-east-1"
     }
   ]

使用encoding/json生成JSON

如果您的目标是生成 JSON,您应该使用 encoding/json包生成有效的 JSON 文档。上面的模板不了解 JSON 语法和上下文,映射条目的值在写入输出时不会转义,因此您最终可能仍会得到无效的 JSON。

最好是像这样生成 JSON:

type Entry struct {
    Name  string `json:"name"`
    Value string `json:"value"`
}

type Params struct {
    Env []Entry `json:"environment"`
}

func main() {
    enc := json.NewEncoder(os.Stdout)
    enc.SetIndent("", "  ") // Optional
    p := &Params{
        Env: []Entry{
            {Name: "name", Value: "test"},
            {Name: "region", Value: "us-east-1"},
        },
    }
    err := enc.Encode(p)
    if err != nil {
        panic(err)
    }
}

输出(在 Go Playground 上尝试):

{
  "environment": [
    {
      "name": "name",
      "value": "test"
    },
    {
      "name": "region",
      "value": "us-east-1"
    }
  ]
}

关于json - 在 go 模板中加入范围 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51043433/

相关文章:

PHP/MySQL : SyntaxError: JSON. 解析:JSON 数据第 1 行第 1 列出现意外字符

python - 比较嵌套字典和列表中的值

android - 创建具有特定结构的 JSON 结果

android - 我想使用 angularjs 和 cordova 将数据发布到 http ://hmkcode. appspot.com/jsonservlet

ios - 使用 JSON 格式从网站获取数据

java - Android 中带有计时器的 Foreach String[]

loops - 在 Common Lisp 循环中定义局部变量

python - PySimpleGUI 循环需要更好的方法

javascript - 如何在 C# 中将 ExpandoObject 转换为字典?

Python::传递一个列表作为参数