如何比较常用键的Map并打印输出?

时间:2017-09-29 10:43:13

标签: go

我有以下代码生成以下输出

代码:

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 := .}}
{{range $element}}{{.Name}}={{.Value}}
{{- end}}
{{- end}}`

func main() {
    data := map[string][]EntetiesClass{
            "Container1": {{"Test", 15}},
            "Container2": {{"Test", 15}},
    }

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

}

链接:https://play.golang.org/p/yM9_wWmyLY
输出:

测试= 15 测试= 15

我想比较Container1和Container2,如果它们有公共密钥,我只想打印输出一次。

输出: 测试= 15

我怎样才能做到这一点?任何帮助表示赞赏?

2 个答案:

答案 0 :(得分:3)

我可以想到两种方法:

  1. 在传递给模板执行之前重新编写数据

    这意味着您可以在传递到t.Execute之前预处理数据以消除重复。您可以使用以下内容执行此操作:

    m := map[EntitiesClass]bool{}
    for _, ... {
        m[ec] = true
        // Or maybe you want to aggregate "Container 1"
        // and "Container 2" in some way
    }
    

    然后您可以传递处理过的数据,模板本身几乎保持不变

  2. 添加custom function for your template

    这意味着您可以添加一个正常的go函数,它可以根据需要接收尽可能多的EntitiesClass并返回重复数据删除(可能使用选项1中的机制)。

    您甚至可以执行以下操作:

    {{if not customHaveSeenThisValueBefore }}
       ...
    {{ endif }}
    
  3. 对于您的简单示例,我会选择选项1,最简单的方法是让模板非常简单。

答案 1 :(得分:0)

这适用于某些过滤逻辑。我正在使用text/template,因为此代码未使用服务器。它与html/template的工作方式相同。当附加到结构的切片时,必须使用指针。如果您不知道为什么会看到herefunc isInSlice() bool需要根据您的需求进行修改。这是一个例子。

package main

import (
    "os"
    "text/template"
)

type Entitie struct {
    Results []*Data
}

type Data struct {
    Name  string
    Value int32
}

// Change this function to mod how to filter
func (e *Entitie) isInSlice(name string) bool {
    for _, item := range e.Results {
        if item.Name == name {
            return true
        }
    }
    return false
}

func (e *Entitie) AddData(name string, value int32) {
    if !e.isInSlice(name) {
        e.Results = append(e.Results, &Data{Name: name, Value: value})
    }
}

// In the template, we use rangeStruct to turn our struct values
// into a slice we can iterate over
var template = `
    {{range $i, $e := .Data.Results}}
        {{$e.Name}} = {{$e.Value}}
    {{end}}
    `

func main() {
    data := make(map[string]Entitie)

    var entities Entitie

    entities.AddData("test", 15)
    entities.AddData("test", 15)
    entities.AddData("test2", 15)

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

    data["Data"] = entities

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

}