【问题标题】:Iterate Go map get index迭代 Go 地图获取索引
【发布时间】:2017-03-22 10:12:42
【问题描述】:

为了在模板中使用reveleven 关键字,我想在使用range 进行迭代时获取映射条目的索引。有什么办法吗? 我的地图结构如下:

map[string][]string

【问题讨论】:

  • 您的地图键是“foo”和“wtf”之类的字符串。什么是偶数字符串?事情不是这样运作的。
  • 必须使用even,还是使用CSS 样式(:nth-child(odd):nth-child(even))而忘记even
  • @kennytm 这实际上解决了我的问题。如果您将其发布为答案,我将接受它,因此案件已结案

标签: dictionary go go-templates revel


【解决方案1】:

在遍历地图时实现索引的简单方法:

package main

import (
    "fmt"
)

func main() {
    mm := map[string]int{"xx" : 1, "gg" : 2}
    cnt := 0
    for a, b:= range mm{
        fmt.Println("a", a, "b",b, "c" , cnt)
        cnt++
    }
    fmt.Println("Hello, playground")
}

然后打印:

a xx b 1 c 0
a gg b 2 c 1
Hello, playground

【讨论】:

    【解决方案2】:

    您不能仅使用模板操作来做到这一点,但您可以注册一个提供必要帮助的函数。

    您可以注册一个返回函数(闭包)的函数,该函数在调用时交替其返回值(“奇数”和“偶数”索引如何交替):

    func isEven() func() bool {
        e := false
        return func() bool {
            e = !e
            return e
        }
    }
    

    我将其命名为 isEven(),以免与 ravel 的 even() 发生冲突。使用它:

    func main() {
        t := template.Must(template.New("").Funcs(template.FuncMap{
            "isEven": isEven,
        }).Parse(templ))
    
        m := map[string]string{
            "a": "A", "b": "B", "c": "C", "d": "D",
        }
        if err := t.Execute(os.Stdout, m); err != nil {
            panic(err)
        }
    }
    
    const templ = `{{$e := isEven}}
    {{- range $k, $v := . -}}
        [even:{{call $e}}] key={{$k}}; value={{$v}}
    {{end}}`
    

    输出(在Go Playground 上试试):

    [even:true] key=a; value=A
    [even:false] key=b; value=B
    [even:true] key=c; value=C
    [even:false] key=d; value=D
    

    如果您想要奇数和偶数迭代的不同输出,您可以在 {{if}} 操作中调用 $e,如下所示:

    const templ = `{{$e := isEven}}
    {{- range $k, $v := . -}}
        [{{if call $e}}even{{else}}odd {{end}}] key={{$k}}; value={{$v}}
    {{end}}`
    

    这个的输出(在Go Playground上试试):

    [even] key=a; value=A
    [odd ] key=b; value=B
    [even] key=c; value=C
    [odd ] key=d; value=D
    

    引擎盖下

    此模板操作:

    {{$e := isEven}}
    

    创建一个名为$e 的新模板变量,其值将是isEven() 函数调用的结果(返回值)。 isEven() 返回一个函数值,一个可以访问 bool 类型的局部变量 e 的闭包。稍后您执行{{call $e}} 时,您不是在调用isEven() Go 函数,而是它返回的函数(闭包)并存储在$e 中。该闭包引用了本地bool 变量e,直到isEvent() 返回的函数可访问,它才会“释放”。

    因此,每当您执行{{call $e}} 时,它都会调用闭包,该闭包“具有”e 类型为bool 的变量,其值在此$e 的调用之间保留。

    如果您再次在模板中调用isEvent,那将返回一个新函数(闭包),包装局部变量e 的新实例,独立于由第一个isEvent() 电话。

    【讨论】:

    • 它的工作原理,但我很好奇,为什么e 每次调用 isEven() 时都不会重置为 false?
    • @Mrlenny 添加了一个新的幕后部分来解释内部结构。
    【解决方案3】:

    Map 条目在 Go 中没有索引;您无法从任何元素中获取索引。此外,每次使用 range 在地图上迭代时,您都会得到不同的顺序 - 另一个暗示地图中没有索引概念。

    索引仅与有序数据结构相关(例如数组、切片、列表等),与映射无关。更多详情请查看https://blog.golang.org/go-maps-in-action

    【讨论】:

      【解决方案4】:
      {{range $key, $element := .Map}}
        {{$index := index .Map $key}}
      {{end}}
      

      【讨论】:

      • 这里的 $index 和 $element 都是 string/[]string。但我想要迭代次数
      • 通过编辑我得到`错误调用索引:无法索引具有字符串类型的切片/数组`​​。我现在在@keynnytm 的评论的帮助下解决了这个问题
      猜你喜欢
      • 1970-01-01
      • 2019-07-26
      • 2017-01-24
      • 2023-04-04
      • 2021-10-08
      • 2011-05-12
      • 2020-05-21
      • 1970-01-01
      • 2016-02-24
      相关资源
      最近更新 更多