如何在go中使用模板进行排名

如何在go中使用模板进行排名,go,go-templates,Go,Go Templates,我有一些json格式的数据 [ { "group":"a", "value":"10" }, { "group":"a", "value":"11" }, { "group":"b", "value":"2" }, { "group":"b", "value":"3" } ] 或者作为一张桌子,让

我有一些json格式的数据

[
    {
        "group":"a",
        "value":"10"

    },
    {
        "group":"a",
        "value":"11"

    },
    {
        "group":"b",
        "value":"2"

    },
    {
        "group":"b",
        "value":"3"

    }
]
或者作为一张桌子,让它更容易阅读

group   value
a       10
a       11
b       2
b       3
我想按
进行排名,以获得

group   value     rank
a       10        1
a       11        2
b       2         1 
b       3         2
在其他语言中,我会使用一个计数器循环遍历数据,当出现新的
值时,计数器会重置。我可以查看数据,但无法让计数器工作。在下面的示例中,似乎在下一次迭代中没有保留上一个计数器值,因此每个值都是1

{{ $counter := 1 }}

{{- range $index, $element := $data }}

  {{ inline (gt $index 0) "," "" }} 

  { 
  "group" : "{{ .group }}", 
  "value" : "{{ .value }}", 
  "rank" : "{{ $counter }}" 
  {{ $counter := add $counter 1 }}
  }

{{- end -}}

在显示例程中实现这种逻辑与go模板的设计理念背道而驰,并且通常违反了go模板的概念

也就是说,模板是一个显示(或“表示”)问题,而您在这里描述的排名是一个排序(或“业务逻辑”)问题。通过在显示组件中执行排序,您正在使程序变得脆弱,因为这些关注点不能相互独立地更改,也不能在一般意义上重用。例如,如果您想将元素打印为JSON或YAML数据,包括它们的排名,您必须重新实现您在文本模板中编写的排名逻辑;如果排名因某种原因而改变,那么你将不得不在多个地方进行更改

更好的方法是创建一个函数,根据需要对元素进行排序,而不依赖于如何显示它们。这样,您的程序在许多方面都更加健壮,主要是因为您只需要在项目更改时对项目进行排序,而不是每次显示项目时

例如():

类型项结构{
组字符串`json:“组”`
Value int`json:“值,字符串”`
Rank int`json:“秩,省略空”`
}
func main(){
//解析项目。
var项目[]项目
err:=json.Unmarshal([]字节(jsonstr),&items)
检查(错误)
//对项目进行排序。
RankItems(项目)
//显示项目。
打印表(项目)
PrintJSON(项目)
printyML(项目)//等。。。
}
func RankItems(xs[]项){
//按组、值对项目进行排序。
sort.Slice(xs,func(i,j int)bool{
x1,x2:=xs[i],xs[j]
如果x1.Group==x2.Group{
返回x1.值
数据来自何处以及存储在何种类型?更新了问题,存储在JSON中的数据可能与您手边的编程语言重复,您无需使用模板引擎,只需在执行模板之前对数据使用
sort.sort
type Item struct {
  Group string `json:"group"`
  Value int    `json:"value,string"`
  Rank  int    `json:"rank,omitempty"`
}

func main() {
  // Parse the items.
  var items []Item
  err := json.Unmarshal([]byte(jsonstr), &items)
  check(err)

  // Rank the items.
  RankItems(items)

  // Display the items.
  PrintTable(items)
  PrintJSON(items)
  PrintYAML(items) // etc...
}

func RankItems(xs []Item) {
  // Order the items by group, value.
  sort.Slice(xs, func(i, j int) bool {
    x1, x2 := xs[i], xs[j]
    if x1.Group == x2.Group {
      return x1.Value < x2.Value
    }
    return x1.Group < x2.Group
  })
  // Rank the items by position within a group.
  var lastGroup string
  var nextRank int
  for i := range xs {
    if i == 0 || lastGroup != xs[i].Group {
      nextRank = 1
    }
    xs[i].Rank = nextRank
    lastGroup = xs[i].Group
    nextRank++
  }
}