In order to use revel
's even
keyword in templates I would like to get the index of a map entry when iterating with range
. Is there any way to do so?
My map has the structure:
map[string][]string
In order to use revel
's even
keyword in templates I would like to get the index of a map entry when iterating with range
. Is there any way to do so?
My map has the structure:
map[string][]string
You can't do this only with template actions, but you may register a function which provides the necessary help.
You may register a function which returns a function (closure), which alternates its return value whenever called (exactly how "odd" and "even" indices alternate):
I named it
isEven()
to not collide with ravel'seven()
. Using it:Output (try it on the Go Playground):
If you want different output for odd and even iterations, you can call
$e
in an{{if}}
action, like this:Output of this (try it on the Go Playground):
Under the hood
This template action:
Creates a new template variable named
$e
, and its value will be the result (return value) of theisEven()
function call.isEven()
returns a function value, a closure that has access to a local variablee
of typebool
. When later you do{{call $e}}
, you're not calling theisEven()
Go function, but the function it returned (the closure) and is stored in$e
. That closure has a reference to the localbool
variablee
, it is not "freed" until the function returned byisEvent()
is accessible.So whenever you do
{{call $e}}
, it calls the closure, which "has" ane
variable of typebool
, whose value is retained between calls of this$e
.If you would call
isEvent
in the template again, that would return a new function (closure), wrapping a new instance of the local variablee
, being independent of the first wrapped variable of the closure returned by the firstisEvent()
call.A Simple way to achieve index while looping through a map:
And prints:
Map entries have no index in Go; there's no way you can get an index out of any element. Also, each time you iterate on a map with
range
, you get a different order - another hint that there's no index concept in maps.Indexes are related to ordered data structures only (e.g. arrays, slices, lists, etc), not maps. Take a look at https://blog.golang.org/go-maps-in-action for more details.