英文:
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中创建了以下代码:
当我尝试在Go中做同样的事情时,我有些困惑,不知道如何做到这一点:
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:
When I am trying to to the same in Go - I somewhat have a mental block, to do this:
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)
}
英文:
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 (
"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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论