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.
CodePudding user response:
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)
}