使用go-templates内的范围检测数组中的最后一项

sen*_*rio 6 go go-templates

该程序输出简单

1,4,2,

但我想打印

1,4,2。

如您所见,逗号在数组的每个项目之后打印。

package main

import "os"
import "text/template"

func main() {
    params := map[string]interface{}{
        "items": [3]int{1, 4, 2},
    }
    tpl := "{{range $i, $el := .items}}{{$el}},{{end}}"
    lister, _ := template.New("foo").Parse(tpl)
    lister.Execute(os.Stdout, params)
}
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以更改,{{range $i, $el := .items}}{{$el}},{{end}}并确保最后一项将打印“。”。代替 ”,”

fhe*_*fhe 6

您可以使用

tpl := "{{range $i, $el := .items}}{{if $i}},{{end}}{{$el}}{{end}}."
Run Code Online (Sandbox Code Playgroud)

实现这一目标。诀窍是先发出逗号分隔符,而不是该范围内的第一项。


icz*_*cza 5

在您发布的简单示例中,最简单的是“fhe”发布的内容:您可以轻松检查当前索引是否是第一个,并在非第​​一个元素后输出逗号。最后输出一个尾随点。

如果在更复杂的示例中,您确实需要检测最后一项,或者您迭代的列表可能为空(因此尾随点将是一个错误),您可以注册一个自定义函数来判断是否当前索引是最后一个:

lister := template.Must(template.New("foo").Funcs(template.FuncMap{
    "IsLast": func(i, size int) bool { return i == size-1 },
}).Parse(tpl))
Run Code Online (Sandbox Code Playgroud)

然后使用以下模板:

tpl := "{{range $i, $el := .items}}{{$el}}{{if IsLast $i (len $.items)}}.{{else}},{{end}}{{end}}"
Run Code Online (Sandbox Code Playgroud)

那么输出将是(在Go Playground上尝试一下):

1,4,2.
Run Code Online (Sandbox Code Playgroud)

这种情况的一种变体可能是注册一个自定义函数,该函数根据长度 ( lastIdx = length - 1) 计算最后一个索引,然后在其中{{range}}您可以进行简单的比较:

tpl := "{{$lastIdx := LastIdx (len .items)}}{{range $i, $el := .items}}{{$el}}{{if eq $lastIdx $i}}.{{else}},{{end}}{{end}}"
lister := template.Must(template.New("foo").Funcs(template.FuncMap{
    "LastIdx": func(size int) int { return size - 1 },
}).Parse(tpl))
Run Code Online (Sandbox Code Playgroud)

输出将是相同的。在Go Playground上尝试一下。