按键聚合对象的映射

huangapple go评论68阅读模式
英文:

Aggregate a map of objects by key

问题

我正在尝试在Go语言中从两个映射中创建一个对象映射。

第一个映射保存键,第二个映射将键作为值与对象关联。

基本上,在这个例子中,有规则和对这些规则的检测。最终,我希望得到一个以规则名称为键,附加到它们的检测的映射(对它们进行聚合)。

最终的结果应该类似于下面的示例(来自下面的TypeScript示例):

[LOG]: {
  "rule1": [
    {
      "name": "rule1",
      "message": "I found rule1"
    },
    {
      "name": "rule1",
      "message": "I found rule1 again"
    }
  ],
  "rule2": [
    {
      "name": "rule2",
      "message": "I found rule2"
    },
    {
      "name": "rule2",
      "message": "I found rule2 again"
    },
    {
      "name": "rule2",
      "message": "I found rule2 another time"
    }
  ]
} 

为了展示这一点,我在TypeScript中创建了以下代码:

Typescript Playground

当我尝试在Go中做同样的事情时,我有些困惑,不知道如何做到这一点:

Go Playground

package main

import (
	"fmt"
)

type Rule struct {
	Name string `json:"name"`
}

type Detection struct {
	Name    string `json:"name"`
	Message string `json:"message"`
}

func main() {

	rules := []Rule{
		{
			Name: "rule1",
		},
		{
			Name: "rule2",
		},
	}

	detected := []Detection{
		{
			Name:    "rule1",
			Message: "I found rule1",
		},
		{
			Name:    "rule1",
			Message: "I found rule1 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 another time",
		},
	}

	fmt.Println(rules)
	fmt.Println(detected)

	aggregatedDetections := map[string][]Detection{}

	for _, r := range rules {
		fmt.Printf("Assign %s to aggregatedDetections\n", r.Name)
	}

	fmt.Println(aggregatedDetections)

}

我知道,Go的老手只需要不到1分钟就能完成这个任务。然而,尽管我认为我对Go中的映射有基本的理解,但我不知道这里期望的是什么。特别是我不知道如何在映射中分配空数组值,以便在下一步中填充它们。

我的问题是:如何获得期望的输出结果。

英文:

I am trying to create a map of objects from two maps in Go.

The first Map holds the keys. The second Map has objects with the keys as values.

Basically in this example - there are rules and detection of these rules. In the end - I want a map with the rule names as keys and a map of detections attached to them (aggregating them).

In the end: I want something like this (taken from the Typescript example below):

[LOG]: {
  "rule1": [
    {
      "name": "rule1",
      "message": "I found rule1"
    },
    {
      "name": "rule1",
      "message": "I found rule1 again"
    }
  ],
  "rule2": [
    {
      "name": "rule2",
      "message": "I found rule2"
    },
    {
      "name": "rule2",
      "message": "I found rule2 again"
    },
    {
      "name": "rule2",
      "message": "I found rule2 another time"
    }
  ]
} 

In order to show this I have created this in Typescript:

Typescript Playground

When I am trying to to the same in Go - I somewhat have a mental block, to do this:

Go Playground

package main

import (
	"fmt"
)

type Rule struct {
	Name string `json:"name"`
}

type Detection struct {
	Name    string `json:"name"`
	Message string `json:"message"`
}

func main() {

	rules := []Rule{
		{
			Name: "rule1",
		},
		{
			Name: "rule2",
		},
	}

	detected := []Detection{
		{
			Name:    "rule1",
			Message: "I found rule1",
		},
		{
			Name:    "rule1",
			Message: "I found rule1 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 another time",
		},
	}

	fmt.Println(rules)
	fmt.Println(detected)

	aggregatedDetections := map[string][]Detection{}

	for _, r := range rules {
		fmt.Printf("Assign %s to aggregatedDetections\n", r.Name)
	}

	fmt.Println(aggregatedDetections)

}

I understand, that a Go veteran will need < 1 Minute for this 按键聚合对象的映射 However: Even though I think I have the basic idea of maps in go - I do no know what is expected here. Especially how I can assign empty array values in the map, in order to populate them in the next step.

My question is finally: How can I get the desired output.

答案1

得分: 2

你可以使用if _, found := map[element]; found {}来检查地图元素是否存在,如果不存在,则创建一个空切片。然后你可以将元素添加到切片中。

请参考以下代码:

package main

import (
	"fmt"
)

type Rule struct {
	Name string `json:"name"`
}

type Detection struct {
	Name    string `json:"name"`
	Message string `json:"message"`
}

func main() {

	rules := []Rule{
		{
			Name: "rule1",
		},
		{
			Name: "rule2",
		},
	}

	detected := []Detection{
		{
			Name:    "rule1",
			Message: "I found rule1",
		},
		{
			Name:    "rule1",
			Message: "I found rule1 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 again",
		},
		{
			Name:    "rule2",
			Message: "I found rule2 another time",
		},
	}

	fmt.Println(rules)
	fmt.Println(detected)

	aggregatedDetections := make(map[string][]Detection)

	for _, r := range rules {
		if _, found := aggregatedDetections[r.Name]; !found {
			aggregatedDetections[r.Name] = make([]Detection, 0)
		}
		msg := ""
		switch {
		case len(aggregatedDetections[r.Name]) == 0:
			msg = "I found " + r.Name
		case len(aggregatedDetections[r.Name]) == 1:
			msg = "I found " + r.Name + " again"
		default:
			msg = "I found " + r.Name + " another time"
		}
		aggregatedDetections[r.Name] = append(aggregatedDetections[r.Name], Detection{
			Name:    r.Name,
			Message: msg,
		})
		fmt.Printf("Assign %s to aggregatedDetections\n", r.Name)
	}

	fmt.Println(aggregatedDetections)

}

Playground

英文:

You can check if a map element is exists with if _, found := map[element]; found {} then if not, create it with an empty slice. Then you can add the elements to the slice.

See code:

package main
import (
&quot;fmt&quot;
)
type Rule struct {
Name string `json:&quot;name&quot;`
}
type Detection struct {
Name    string `json:&quot;name&quot;`
Message string `json:&quot;message&quot;`
}
func main() {
rules := []Rule{
{
Name: &quot;rule1&quot;,
},
{
Name: &quot;rule2&quot;,
},
}
detected := []Detection{
{
Name:    &quot;rule1&quot;,
Message: &quot;I found rule1&quot;,
},
{
Name:    &quot;rule1&quot;,
Message: &quot;I found rule1 again&quot;,
},
{
Name:    &quot;rule2&quot;,
Message: &quot;I found rule2&quot;,
},
{
Name:    &quot;rule2&quot;,
Message: &quot;I found rule2 again&quot;,
},
{
Name:    &quot;rule2&quot;,
Message: &quot;I found rule2 another time&quot;,
},
}
fmt.Println(rules)
fmt.Println(detected)
aggregatedDetections := make(map[string][]Detection)
for _, r := range rules {
if _, found := aggregatedDetections[r.Name]; !found {
aggregatedDetections[r.Name] = make([]Detection, 0)
}
msg := &quot;&quot;
switch {
case len(aggregatedDetections[r.Name]) == 0:
msg = &quot;I found &quot; + r.Name
case len(aggregatedDetections[r.Name]) == 1:
msg = &quot;I found &quot; + r.Name+&quot; again&quot;
default: 		     
msg = &quot;I found &quot; + r.Name+&quot; another time&quot;
}
aggregatedDetections[r.Name] = append(aggregatedDetections[r.Name], Detection{
Name: r.Name,
Message: msg,
})
fmt.Printf(&quot;Assign %s to aggregatedDetections\n&quot;, r.Name)
}
fmt.Println(aggregatedDetections)
}

Playground

huangapple
  • 本文由 发表于 2022年9月25日 23:06:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/73845551.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定