英文:
Go template remove the last comma in range loop
问题
我有这样的代码:
package main
import (
"text/template"
"os"
)
func main() {
type Map map[string]string
m := Map {
"a": "b",
"c": "d",
}
const temp = `{{range $key, $value := $}}key:{{$key}} value:{{$value}},{{end}}`
t := template.Must(template.New("example").Parse(temp))
t.Execute(os.Stdout, m)
}
它会输出:
key:a value:b,key:c value:d,
但我想要这样的输出:
key:a value:b,key:c value:d
我不需要最后的逗号,如何去掉它。我在这里找到了一个关于循环数组的解决方案:https://groups.google.com/d/msg/golang-nuts/XBScetK-guk/Bh7ZFz6R3wQJ,但我无法为映射获取索引。
英文:
I have code like this:
package main
import (
"text/template"
"os"
)
func main() {
type Map map[string]string
m := Map {
"a": "b",
"c": "d",
}
const temp = `{{range $key, $value := $}}key:{{$key}} value:{{$value}},{{end}}`
t := template.Must(template.New("example").Parse(temp))
t.Execute(os.Stdout, m)
}
it will output :
> key:a value:b,key:c value:d,
but I want something like this:
> key:a value:b,key:c value:d
I don't need the last comma, how to remove it. I found a solution for looping an array here: https://groups.google.com/d/msg/golang-nuts/XBScetK-guk/Bh7ZFz6R3wQJ , but I can't get index for a map.
答案1
得分: 23
自Go 1.11版本开始,可以更改模板变量的值。这使得我们可以在模板之外,无需自定义函数的情况下实现这一点。
以下模板可以实现这一点:
{{$first := true}}
{{range $key, $value := $}}
{{if $first}}
{{$first = false}}
{{else}}
,
{{end}}
key:{{$key}} value:{{$value}}
{{end}}
下面是问题中修改后的工作示例:
type Map map[string]string
m := Map{
"a": "b",
"c": "d",
"e": "f",
}
const temp = `{{$first := true}}{{range $key, $value := $}}{{if $first}}{{$first = false}}{{else}}, {{end}}key:{{$key}} value:{{$value}}{{end}}`
t := template.Must(template.New("example").Parse(temp))
t.Execute(os.Stdout, m)
在Go Playground上尝试运行后,输出结果如下:
key:a value:b, key:c value:d, key:e value:f
英文:
Since Go 1.11 it is now possible to change values of template variables. This gives us the possibility to do this without the need of a custom function (being outside of the template).
The following template does that:
{{$first := true}}
{{range $key, $value := $}}
{{if $first}}
{{$first = false}}
{{else}}
,
{{end}}
key:{{$key}} value:{{$value}}
{{end}}
Here's the altered working example from the question:
type Map map[string]string
m := Map{
"a": "b",
"c": "d",
"e": "f",
}
const temp = `{{$first := true}}{{range $key, $value := $}}{{if $first}}{{$first = false}}{{else}}, {{end}}key:{{$key}} value:{{$value}}{{end}}`
t := template.Must(template.New("example").Parse(temp))
t.Execute(os.Stdout, m)
Which outputs (try it on the Go Playground):
key:a value:b, key:c value:d, key:e value:f
答案2
得分: 9
以下是如何使用模板函数编写逗号分隔的键值对的方法。
声明一个返回递增并返回计数器的函数:
func counter() func() int {
i := -1
return func() int {
i++
return i
}
}
将此函数添加到模板中:
t := template.Must(template.New("example").Funcs(template.FuncMap{"counter": counter}).Parse(temp))
在模板中使用它:
{{$c := counter}}{{range $key, $value := $}}{{if call $c}}, {{end}}key:{{$key}} value:{{$value}}{{end}}
此模板在键值对之前写入分隔符,而不是在键值对之后。
计数器在循环之前创建,并在每次循环迭代时递增。第一次循环时不会写入分隔符。
模板中的逻辑可以通过将 if 语句移到 Go 代码中来简化:
func separator(s string) func() string {
i := -1
return func() string {
i++
if i == 0 {
return ""
}
return s
}
}
将该函数添加到模板中:
t := template.Must(template.New("example").Funcs(template.FuncMap{"separator": separator}).Parse(temp))
像这样使用它:
{{$s := separator ", "}}{{range $key, $value := $}}{{call $s}}key:{{$key}} value:{{$value}}{{end}}
英文:
Here's how to write comma separated key-value pairs using a template function.
Declare a function that returns a function that increments and returns a counter:
func counter() func() int {
i := -1
return func() int {
i++
return i
}
}
Add this function to the template:
t := template.Must(template.New("example").Funcs(template.FuncMap{"counter": counter}).Parse(temp))
Use it in the template like this:
{{$c := counter}}{{range $key, $value := $}}{{if call $c}}, {{end}}key:{{$key}} value:{{$value}}{{end}}
This template writes the separators before the key-value pairs instead after the pairs.
The counter is created before the loop and incremented on each iteration through the loop. The separator is not written the first time through the loop.
The logic in the template can be simplified by moving the if statement to Go code:
func separator(s string) func() string {
i := -1
return func() string {
i++
if i == 0 {
return ""
}
return s
}
}
Add the function to the template:
t := template.Must(template.New("example").Funcs(template.FuncMap{"separator": separator}).Parse(temp))
Use it like this:
{{$s := separator ", "}}{{range $key, $value := $}}{{call $s}}key:{{$key}} value:{{$value}}{{end}}
答案3
得分: 0
我使用以下模板来正确格式化一些 JSON,使用 go 模板语言。
它可以处理任意大小的集合,包括空集合。
{{- define "JoinList" -}}
{{- $lastIndex := math.Sub (len .) 1 -}}
{{- range $index, $property := . -}}
{{ if isKind "string" $property.value }}
"{{ $property.key }}": "{{ $property.value }}"{{ if ne $index $lastIndex }},{{ end }}
{{- else -}}
"{{ $property.key }}": {{ $property.value }}{{ if ne $index $lastIndex }},{{ end }}
{{ end }}
{{- end -}}
{{- end -}}
英文:
I used the below template to correctly format some JSON using a go template.
It handles a collection of any size or empty.
{{- define "JoinList" -}}
{{- $lastIndex := math.Sub (len .) 1 -}}
{{- range $index, $property := . -}}
{{ if isKind "string" $property.value }}
"{{ $property.key }}": "{{ $property.value }}"{{ if ne $index $lastIndex }},{{ end }}
{{- else -}}
"{{ $property.key }}": {{ $property.value }}{{ if ne $index $lastIndex }},{{ end }}
{{ end }}
{{- end -}}
{{- end -}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论