here are my initial model
type Team struct {
Id string `json:"id"`
Name string `json:"name"`
Level int64 `json:"level"`
}
type TeamTree struct {
Teams []Team `json:"teams"`
Child []TeamTree `json:"child"`
}
Sample data:
id team level
a BOD 1
b Marketing 2
c Dev 2
d Worker 3
I want to have this result (should be a mapping):
{
"teams": [
{"id": "a", "team": "BOD", "level": 1}
],
"child": {
"teams": [
{"id":"b", "team": "marketing", "level": 2},
{"id":"c", "team": "marketing", "level": 2}
],
"child": {
"teams": [
{"id": "d", "team": "worker", "level": 3}
],
"child"": {}
}
}
}
I was told to do self loop, but I do not know how to do it, since I keep getting error and my code cant even run.
This is a full example of what you want
package main
import "log"
type Team struct {
id string
name string
level int64
}
type TeamTree struct {
teams []Team
children []TeamTree
}
func main() {
firstChild := TeamTree{teams: []Team{{id: "firstChildId", name: "First", level: 10}}, children: make([]TeamTree, 0)}
secondChild := TeamTree{teams: []Team{{id: "secondChildId", name: "Second", level: 20}}, children: make([]TeamTree, 0)}
thirdChild := TeamTree{teams: []Team{{id: "thirdChildId", name: "Third", level: 30}}, children: make([]TeamTree, 0)}
rootTeamTree := TeamTree{teams: []Team{{id: "rootId", name: "Root", level: 100}}, children: []TeamTree{firstChild, secondChild, thirdChild}}
log.Println("What's the second child's level:", rootTeamTree.children[1].teams[0].level)
}
And this is the result
2022/06/19 08:24:55 What's the second child's level: 20
Related
I have a struct like that.
type Category struct {
ID int `json:"id"`
MetaDescription string `json:"metaDescription" gorm:"column:metadescription"`
MetaTitle string `json:"metaTitle" gorm:"column:metatitle"`
Name string `json:"name" gorm:"column:categoryname"`
Order int `json:"order" gorm:"column:categoryorder"`
ParentId int `json:"parentId" gorm:"column:parentid"`
Rank float64 `json:"rank" gorm:"column:rank"`
Url string `json:"url" gorm:"column:catname4seo"`
}
I'm fetching this data from a database and I want to manipulate it to create a category tree. My tree would be like that
type CategoryTree struct {
ID int `json:"id"`
Name string `json:"name" gorm:"column:categoryname"`
Url string `json:"url" gorm:"column:catname4seo"`
SubCategories []CategoryTree `json:"subCategories"`
}
Normally, I am a JavaScript dev and a newbie in GoLang so especially static type made me harder. That's why I couldn't achieve it. Can you help me to do so?
Thanks in advance.
I think this is an algorithm question. Just iterating over the Category list, and push elements into CategoryTree. Go code like this:
package main
import (
"encoding/json"
"fmt"
)
type Category struct {
ID int `json:"id"`
MetaDescription string `json:"metaDescription" gorm:"column:metadescription"`
MetaTitle string `json:"metaTitle" gorm:"column:metatitle"`
Name string `json:"name" gorm:"column:categoryname"`
Order int `json:"order" gorm:"column:categoryorder"`
ParentId int `json:"parentId" gorm:"column:parentid"`
Rank float64 `json:"rank" gorm:"column:rank"`
Url string `json:"url" gorm:"column:catname4seo"`
}
// load db data by CategoryTree instead of Category
type CategoryTree struct {
Category
SubCategories []*CategoryTree `json:"subCategories"`
}
func main() {
input := []*CategoryTree{
{
Category: Category{
ID: 1,
ParentId: 0,
},
},
{
Category: Category{
ID: 2,
ParentId: 1,
},
},
{
Category: Category{
ID: 3,
ParentId: 1,
},
},
{
Category: Category{
ID: 4,
ParentId: 2,
},
},
}
tree := makeTree(input)
output, _ := json.MarshalIndent(tree, "", " ")
fmt.Printf("%s\n", string(output))
}
func makeTree(list []*CategoryTree) *CategoryTree {
dataMap := make(map[int]*CategoryTree, len(list))
var rootNode *CategoryTree
for i := range list {
// root node has min ParentID
if rootNode == nil || rootNode.ParentId > list[i].ParentId {
rootNode = list[i]
}
// list to map
dataMap[list[i].ID] = list[i]
}
// build tree
for i := range list {
parentNode, ok := dataMap[list[i].ParentId]
if !ok {
continue
}
if parentNode.SubCategories == nil {
parentNode.SubCategories = []*CategoryTree{}
}
parentNode.SubCategories = append(parentNode.SubCategories, list[i])
}
return rootNode
}
and output:
{
"id": 1,
"metaDescription": "",
"metaTitle": "",
"name": "",
"order": 0,
"parentId": 0,
"rank": 0,
"url": "",
"subCategories": [
{
"id": 2,
"metaDescription": "",
"metaTitle": "",
"name": "",
"order": 0,
"parentId": 1,
"rank": 0,
"url": "",
"subCategories": [
{
"id": 4,
"metaDescription": "",
"metaTitle": "",
"name": "",
"order": 0,
"parentId": 2,
"rank": 0,
"url": "",
"subCategories": null
}
]
},
{
"id": 3,
"metaDescription": "",
"metaTitle": "",
"name": "",
"order": 0,
"parentId": 1,
"rank": 0,
"url": "",
"subCategories": null
}
]
}
If I have this array:
type Person struct {
ID string `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
}
var Group = []Person{
{
ID: "1",
Name: "Linda",
Address: "London",
},
{
ID: "2",
Name: "George",
Address: "Paris",
},
{
ID: "3",
Name: "John",
Address: "Amsterdam",
},
}
How can I generate an object of objects in each of which a particular value is the key and the rest of the key-value pairs are in, as in:
var Object = {
Linda: {
ID: "1",
Address: "London",
},
George: {
ID: "2",
Address: "Paris",
},
John: {
ID: "3",
Address: "Amsterdam",
},
}
Not the smartest question in town I know, but please help!
I'm not entirely sure what you mean by Object here but one way to accomplish this would be via a map.
For example:
package main
import "fmt"
func main(){
type Person struct {
ID string `json:"id"`
Name string `json:"name"`
Address string `json:"address"`
}
var Group = []Person{
{
ID: "1",
Name: "Linda",
Address: "London",
},
{
ID: "2",
Name: "George",
Address: "Paris",
},
{
ID: "3",
Name: "John",
Address: "Amsterdam",
},
}
personMap := map[string]Person{}
for _, person := range Group {
personMap[person.Name] = person
}
fmt.Println(personMap)
// Outputs: map[George:{2 George Paris} John:{3 John Amsterdam} Linda:{1 Linda London}]
}
You could then access an a Person from the map via personMap["Linda"]
This question already has answers here:
json.Marshal(struct) returns "{}"
(3 answers)
Closed 1 year ago.
My model having following data:
package main
type Subject struct {
name string `json:name`
section int `json:section`
}
var subjects = map[string][]Subject{
"1001": []Subject{
{
name: "Phy",
section: 1,
},
{
name: "Phy",
section: 2,
},
},
"1002": []Subject{
{
name: "Chem",
section: 1,
},
{
name: "Chem",
section: 2,
},
},
"1003": []Subject{
{
name: "Math",
section: 1,
},
{
name: "Math",
section: 2,
},
},
"1004": []Subject{
{
name: "Bio",
section: 1,
},
{
name: "Bio",
section: 2,
},
},
}
I am creating route as follows:
route.GET("/subjects/:id", func(c *gin.Context) {
id := c.Param("id")
subjects := subjects[id]
c.JSON(http.StatusOK, gin.H{
"StudentID": id,
"Subject": subjects,
})
})
It tried to call it using postman as : localhost:8080/subjects/1001
but it just shows {} {} instead of array of subject struct's objects.
Output:
{
"StudentID": "1001",
"Subject": [
{},
{}
]
}
This is because your Subject uses lowercase fields name and section and thus will not be serialized.
Changing it to:
type Subject struct {
Name string `json:"name"`
Section int `json:"section"`
}
Will show the fields:
{
"StudentID": "1001",
"Subject": [
{"name":"Phy","section":1},
{"name":"Phy","section":2}
]
}
I am working on a project where I have to create one to many relationships which will get all the list of records referenced by id in another table and I have to display all the selected data in the multi-select field (selectArrayInput). Please help me out in this, if you help with an example that would be great.
Thanks in advance.
Example:
district
id name
1 A
2 B
3 C
block
id district_id name
1 1 ABC
2 1 XYZ
3 2 DEF
I am using https://github.com/Steams/ra-data-hasura-graphql hasura-graphql dataprovider for my application.
You're likely looking for "nested object queries" (see: https://hasura.io/docs/1.0/graphql/manual/queries/nested-object-queries.html#nested-object-queries)
An example...
query MyQuery {
district(where: {id: {_eq: 1}}) {
id
name
blocks {
id
name
}
}
}
result:
{
"data": {
"district": [
{
"id": 1,
"name": "A",
"blocks": [
{
"id": 1,
"name": "ABC"
},
{
"id": 2,
"name": "XYZ"
}
]
}
]
}
}
Or...
query MyQuery2 {
block(where: {district: {name: {_eq: "A"}}}) {
id
name
district {
id
name
}
}
}
result:
{
"data": {
"block": [
{
"id": 1,
"name": "ABC",
"district": {
"id": 1,
"name": "A"
}
},
{
"id": 2,
"name": "XYZ",
"district": {
"id": 1,
"name": "A"
}
}
]
}
}
Setting up the tables this way...
blocks:
districts:
Aside: I recommend using plural table names as they are more standard, "districts" and "blocks"
I'm new in go and tried to populate slice data by same values in GO.
Refer to the following example
input struct {
ID string `json:"id"`
Name string `json:"name"`
Image string `json:"image"`
}
output struct {
ID string `json:"id"`
Name string `json:"name"`
Image []img `json:"image"`
}
img struct {
Name string `json:"name"`
Width int `json:"width"`
Height int `json:"height"`
}
input = [{
"id": 10,
"name": "product 10",
"image": {"name": "https://i.imgur.com/eKSk6Fq.jpg"}
}, {
"id": 10,
"name": "product 10",
"image": {"name": "https://i.imgur.com/np1wmxw.jpg"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "https://i.imgur.com/jlFgGpe.jpg"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "https://i.imgur.com/B0D4iRk.jpg"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "https://i.imgur.com/4AiXzf8.jpg"}
}]
// expected output
output = [{
"id": 10,
"name": "product 10",
"image": [{
"name": "https://i.imgur.com/eKSk6Fq.jpg",
"width": 900,
"height": 600
}, {
"name": "https://i.imgur.com/np1wmxw.jpg",
"width": 600,
"height": 600
}]
}, {
"id": 11,
"name": "product 11",
"image": [{
"name": "https://i.imgur.com/jlFgGpe.jpg",
"width": 639,
"height": 700
}, {
"name": "https://i.imgur.com/B0D4iRk.jpg",
"width": 1280,
"height": 960
}, {
"name": "https://i.imgur.com/4AiXzf8.jpg",
"width": 540,
"height": 405
}]
}]
I would like to group input to a new slice based on the same ID,
so the result output would be new slice of new struct with grouped image with same ID.
H̶o̶w̶ ̶w̶o̶u̶l̶d̶ ̶I̶ ̶a̶c̶h̶i̶e̶v̶e̶d̶ ̶t̶h̶e̶ ̶̶o̶u̶t̶p̶u̶t̶̶ ̶r̶e̶s̶u̶l̶t̶ ̶u̶s̶i̶n̶g̶ ̶G̶O̶? update: got the answer from Peter Eichelsheim
Also, if I had to ge image size in the input with http.get and want to use goroutine, how would I achieve the result? since my last code here playground not achieving the correct output (always get the last input)
note: I don't know why I get null in go playground, but in my laptop the result is: [{"id":11,"name":"product 11","image":[{"name":"https://i.imgur.com/B0D4iRk.jpg","width":1280,"height":960}]}]
In PHP, I would do something below to achieve the intended output.
foreach ($input as $key => $value) {
if (!isset($output[$value["id"]])) {
$output[$value["id"]] = [
"id" => $value["id"],
"name" => $value["name"],
"image" => [],
];
}
$get = getimagesize($value["image"]["name"]);
if ($get) {
$width = isset($get[0]) ? $get[0] : 0;
$height = isset($get[1]) ? $get[1] : 0;
}
$output[$value["id"]]["image"][$key] = [
"name" => $value["image"]["name"],
"width" => $width,
"height" => $height,
];
$output[$value["id"]]["image"] = array_values($output[$value["id"]]["image"]);
}
$output = array_values($output);
$json = json_encode($output, true);
echo $json;
Thanks
Here a little sample with sample json input, using map[int]output to club images into the same product ID.
package main
import (
"encoding/json"
"fmt"
"log"
)
type input struct {
ID int `json:"id"`
Name string `json:"name"`
Image img `json:"image"`
}
type output struct {
ID int `json:"id"`
Name string `json:"name"`
Image []img `json:"image"`
}
type img struct {
Name string `json:"name"`
}
func main() {
var jsoninput = []byte(`
[{
"id": 10,
"name": "product 10",
"image": {"name": "image 10a"}
}, {
"id": 10,
"name": "product 10",
"image": {"name": "image 10b"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "image 11a"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "image 11b"}
}, {
"id": 11,
"name": "product 11",
"image": {"name": "image 11c"}
}]`)
var inputs []input
err := json.Unmarshal(jsoninput, &inputs)
if err != nil {
log.Fatalln("could not Unmarshal:", err)
}
var outputlist = make(map[int]output)
for _, inp := range inputs {
outputlist[inp.ID] = output{inp.ID, inp.Name, append(outputlist[inp.ID].Image, inp.Image)}
}
var outputs []output
for _, outp := range outputlist{
outputs = append(outputs,outp)
}
jsonoutput, err := json.Marshal(outputs)
fmt.Println(string(jsonoutput))
}
var inputs []input // assuming the json has been unmarshalled correctly
outs := make(map[int]output)
// this will create a map, keyed by id, values are groups of inputs
for _, input := range inputs {
out, exists := outs[input.ID]
if !exists {
out = output{
ID: input.ID,
Name: input.Name,
}
}
out.Image = append(out.Image, img{Name: input.Name})
}
output := make([]output, len(outs))
var idx int
for key, out := range outs {
output[idx] = out
idx++
}