Iterasi melalui peta di template

94

Saya mencoba menampilkan daftar kelas gym (Yoga, Pilates, dll). Untuk setiap jenis kelas ada beberapa kelas, jadi saya ingin mengelompokkan semua kelas Yoga, dan semua kelas Pilates, dan seterusnya.

Saya membuat fungsi ini untuk mengambil sepotong dan membuat petanya

func groupClasses(classes []entities.Class) map[string][]entities.Class {
    classMap := make(map[string][]entities.Class)
    for _, class := range classes {
        classMap[class.ClassType.Name] = append(classMap[class.ClassType.Name], class)
    }
    return classMap
}

Masalahnya sekarang bagaimana saya bisa mengulanginya, menurut http://golang.org/pkg/text/template/ , Anda perlu mengaksesnya dalam .Keyformat, saya tidak tahu kuncinya (kecuali saya juga memberikan sepotong kunci ke dalam template). Bagaimana cara membongkar peta ini dalam pandangan saya.

Yang saya miliki saat ini adalah

{{ . }} 

yang menampilkan sesuatu seperti:

map[Pilates:[{102 PILATES ~/mobifit/video/ocen.mpg 169 40 2014-05-03 23:12:12 +0000 UTC 2014-05-03 23:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC {PILATES Pilates 1 2014-01-22 21:46:16 +0000 UTC} {1 [email protected] password SUPERADMIN Lee Brooks {Male true} {1990-07-11 00:00:00 +0000 UTC true} {1.85 true} {88 true} 2014-01-22 21:46:16 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false}} [{1 Mat 2014-01-22 21:46:16 +0000 UTC}]} {70 PILATES ~/mobifit/video/ocen.mpg 119 66 2014-03-31 15:12:12 +0000 UTC 2014-03-31 15:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC 
Lee
sumber

Jawaban:

169

Periksa bagian Variabel di dokumen template Go. Rentang dapat mendeklarasikan dua variabel, dipisahkan dengan koma. Berikut ini seharusnya bekerja:

{{ range $key, $value := . }}
   <li><strong>{{ $key }}</strong>: {{ $value }}</li>
{{ end }}
Herman Schaaf
sumber
47

Seperti yang dikatakan Herman, Anda bisa mendapatkan indeks dan elemen dari setiap iterasi.

{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}

Contoh kerja:

package main

import (
    "html/template"
    "os"
)

type EntetiesClass struct {
    Name string
    Value int32
}

// In the template, we use rangeStruct to turn our struct values
// into a slice we can iterate over
var htmlTemplate = `{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}`

func main() {
    data := map[string][]EntetiesClass{
        "Yoga": {{"Yoga", 15}, {"Yoga", 51}},
        "Pilates": {{"Pilates", 3}, {"Pilates", 6}, {"Pilates", 9}},
    }

    t := template.New("t")
    t, err := t.Parse(htmlTemplate)
    if err != nil {
        panic(err)
    }

    err = t.Execute(os.Stdout, data)
    if err != nil {
        panic(err)
    }

}

Keluaran:

Pilates
3
6
9

Yoga
15
51

Taman bermain: http://play.golang.org/p/4ISxcFKG7v

ANisus
sumber
Hai @ANisus, saya memiliki persyaratan untuk menghasilkan json melalui template seperti di bawah ini tetapi juga memiliki koma tambahan seperti di address array di contoh yang diberikan Output `` `{" name ":" Mus "," adresses ": [{" address ":" A "}, {" address ":" B "},]}` `Contoh link kode play.golang.org/p/nD08y0noPHv
Mohammad Mustaqeem
1
@MohammadMustaqeem Anda dapat memeriksa indeks setiap iterasi, dan tidak menambahkan koma pada iterasi pertama. Lihat contoh: play.golang.org/p/5544hc_0_g8 . Hati-hati. Merender JSON dengan template akan menyebabkan masalah pelolosan. Lihat alamat "C & D" yang saya tambahkan.
ANisus
Terima kasih. Saya telah memecahkan masalah pelarian dengan mengimpor "teks / template" alih-alih "html / template". play.golang.org/p/PXTNZGWx7Yi
Mohammad Mustaqeem
1
@MohammadMustaqeem Sayangnya Anda sekarang mungkin mendapatkan JSON yang tidak valid, atau lebih buruk lagi, JSON yang diinjeksi: play.golang.org/p/kd9bM_rpwyg . Menggunakan template untuk menghasilkan json tidak bijaksana, tetapi jika Anda harus, escape nilai JSON dengan fungsi seperti js (juga dalam contoh ini).
ANisus