模板范围中的最后一项

问题描述 投票:9回答:2

鉴于模板:

{{range $i, $e := .SomeField}}
        {{if $i}}, {{end}}
        $e.TheString
{{end}}

这可以输出:

one, two, three

但是,如果我要输出:

one, two, and three

我需要知道哪个是上面范围内的最后一个元素。

我可以设置一个变量来保存数组.SomeField的长度,但是它总是3,并且上面的$i值只会变为2.而且你不能在我看到的模板中执行算术运算。

是否可以检测模板范围中的最后一个值?干杯。

go go-templates
2个回答
14
投票

这可能不是最优雅的解决方案,但它是我能找到的最好的解决方案:

http://play.golang.org/p/MT91mLqk1s

package main

import (
    "os"
    "reflect"
    "text/template"
)

var fns = template.FuncMap{
    "last": func(x int, a interface{}) bool {
        return x == reflect.ValueOf(a).Len() - 1
    },
}


func main() {
    t := template.Must(template.New("abc").Funcs(fns).Parse(`{{range  $i, $e := .}}{{if $i}}, {{end}}{{if last $i $}}and {{end}}{{$e}}{{end}}.`))
    a := []string{"one", "two", "three"}
    t.Execute(os.Stdout, a)
}

注意:您也可以在不使用len函数的情况下执行此操作(信用证给Russ Cox):http://play.golang.org/p/V94BPN0uKD

C.F.


1
投票

今天我们在docker inspect命令中使用format时遇到了同样的问题。在没有修补Docker的情况下获取最后一个元素的最简单方法是(表达式已被拆分为多行以便于阅读):

{{ $image := "" }}
{{ range split .ContainerImageName "/" }}
    {{ $image = . }}{{ end }}
{{ index (split $image ":") 0 }}

所以在我们的例子中,我们需要没有注册表地址和版本的图像名称。例如,像registry.domain.local / images / nginx:latest这样的图像名称变为nginx。

P.S:你需要Go> = 1.11来完成这项工作(https://github.com/golang/go/issues/10608

P.P.S:问题是关于Go模板,但对于那些在这里遇到与Docker相同问题的配置示例:

1)在daemon.json中使用Go模板

cat /etc/docker/daemon.json

{
    "log-driver": "syslog",
    "log-opts": {
        "syslog-address": "udp://127.0.0.1:20627",
        "tag": "{{ $image :=  \"\" }}{{ range split .ContainerImageName \"/\" }}{{ $image = . }}{{ end }}{{ index (split $image \":\") 0 }}/{{.Name}}"
}

2)使用带有-f选项的Go模板:

docker inspect \
  -f '{{ $image := "" }}{{ range split .Config.Image "/" }}{{ $image = . }}{{ end }}{{ index (split $image ":") 0 }}' \
  <container>
© www.soinside.com 2019 - 2024. All rights reserved.