Last item in a template range

前端 未结 2 728
一整个雨季
一整个雨季 2021-02-07 08:47

Given the template:

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

This can output:

one         


        
相关标签:
2条回答
  • 2021-02-07 09:14

    We had same problem today when working with format in docker inspect command. The easiest way to get the last element without patching Docker was (the expression has been split into lines for ease of reading):

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

    So in our case, we needed the image name without registry address and version. For example, image name like registry.domain.local/images/nginx:latest becomes nginx.

    P.S: You need Go >= 1.11 to do the job (https://github.com/golang/go/issues/10608)

    P.P.S: The question was about Go template but for those who had same problems with Docker here the configuration examples:

    1) Using Go template in daemon.json

    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) Using Go template with -f option:

    docker inspect \
      -f '{{ $image := "" }}{{ range split .Config.Image "/" }}{{ $image = . }}{{ end }}{{ index (split $image ":") 0 }}' \
      <container>
    
    0 讨论(0)
  • 2021-02-07 09:30

    This is probably not the most elegant solution but it's the best I could find:

    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)
    }
    

    Note: You can also do it without reflect using the len function (credit to Russ Cox): http://play.golang.org/p/V94BPN0uKD

    c.f.

    • https://groups.google.com/forum/#!topic/golang-nuts/yRXHSCjVAcM
    • https://groups.google.com/forum/#!msg/golang-nuts/XBScetK-guk/Bh7ZFz6R3wQJ
    • https://groups.google.com/forum/#!topic/golang-nuts/mqRbR7AFJj0
    0 讨论(0)
提交回复
热议问题