Итерация по карте в шаблоне

94

Я пытаюсь отобразить список занятий в тренажерном зале (йога, пилатес и т. Д.). Для каждого типа занятий есть несколько занятий, поэтому я хочу сгруппировать все занятия йогой, все занятия пилатесом и так далее.

Я сделал эту функцию, чтобы взять срез и составить его карту

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
}

Проблема теперь в том, как я могу перебирать его, согласно http://golang.org/pkg/text/template/ , вам нужно получить к нему доступ в .Keyформате, я не знаю ключей (если я также не передал срез ключей в шаблон). Как мне распаковать эту карту в моем представлении.

Все, что у меня есть сейчас, это

{{ . }} 

который отображает что-то вроде:

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 leebrooks0@gmail.com 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 
Ли
источник

Ответы:

171

Проверьте раздел «Переменные» в документации по шаблону Go. Диапазон может объявлять две переменные, разделенные запятой. Следующее должно работать:

{{ range $key, $value := . }}
   <li><strong>{{ $key }}</strong>: {{ $value }}</li>
{{ end }}
Герман Шааф
источник
47

Как указал Герман, вы можете получить индекс и элемент из каждой итерации.

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

Рабочий пример:

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

}

Выход:

Pilates
3
6
9

Yoga
15
51

Площадка: http://play.golang.org/p/4ISxcFKG7v

Анисус
источник
Привет, @ANisus, у меня есть требование генерировать json с помощью шаблона, как показано ниже, но в нем также есть дополнительные запятые, как в массиве адресов в данном примере. Выходные данные `` `{" name ":" Mus "," adresses ": [{" address ":" A "}, {" address ":" B "},]}` `` Ссылка на пример кода play.golang.org/p/nD08y0noPHv
Мохаммад Мустаким
1
@MohammadMustaqeem Вы можете проверять индекс каждой итерации, но не добавлять запятую на первой итерации. См. Пример: play.golang.org/p/5544hc_0_g8 . Просто будь осторожен. Визуализация JSON с помощью шаблонов вызовет проблемы с экранированием. См. Добавленный мною адрес «C&D».
ANisus
Спасибо. Я решил проблему с экранированием, импортировав «text / template» вместо «html / template». play.golang.org/p/PXTNZGWx7Yi
Мохаммад Мустаким
1
@MohammadMustaqeem К сожалению, теперь вы можете получить недопустимый JSON или, что еще хуже, внедренный JSON: play.golang.org/p/kd9bM_rpwyg . Использование шаблона для генерации json неразумно, но если вам нужно, избегайте значений JSON с помощью таких функций, как js (также в этом примере).
ANisus