Created
August 23, 2023 23:27
-
-
Save dlford/9e66069cfc7fb9afc649c5e3dc650083 to your computer and use it in GitHub Desktop.
Example Go Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
) | |
// Comment from Database | |
type Comment struct { | |
ID string `json:"id""` | |
ParentID string `json:"pid"` | |
Text string `json:"text"` | |
} | |
// NestedComment output | |
type NestedComment struct { | |
Comment | |
Children []NestedComment `json:"children,omitempty"` | |
} | |
func main() { | |
// Some comment data from DB | |
jsondata := `[{"id":"f1c3a838-f4b4-4ebd-bb1b-d3e4c0dce27d","pid":"6a162b3f-9341-46e9-95f7-dedc6cd06868","text":"comment 1"},{"id":"131cf4bb-1971-43a2-992f-2cbb042a4184","pid":"","text":"comment 2"},{"id":"4c93a789-ecab-4173-954c-b039cd3a9e17","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 3"},{"id":"c7974b6d-67e1-47d0-84fa-c78d51682df2","pid":"131cf4bb-1971-43a2-992f-2cbb042a4184","text":"comment 4"},{"id":"386c4439-4596-47c1-99bf-cb479055fe5a","pid":"","text":"comment 5"},{"id":"5ef0816e-ea13-4a7e-8009-e67ee08ef906","pid":"386c4439-4596-47c1-99bf-cb479055fe5a","text":"comment 6"},{"id":"96b0a536-602b-4f3f-a352-020f22cdfb18","pid":"","text":"comment 7"},{"id":"d0f11e98-deea-4fd5-becb-8f406ebcae83","pid":"96b0a536-602b-4f3f-a352-020f22cdfb18","text":"comment 8"},{"id":"bad87461-3cbf-4ecb-a8c7-36876b57d652","pid":"","text":"comment 9"},{"id":"e3ee6f90-495f-4348-9c29-bd6e15ec3b39","pid":"bad87461-3cbf-4ecb-a8c7-36876b57d652","text":"comment 10"},{"id":"6a162b3f-9341-46e9-95f7-dedc6cd06868","pid":"","text":"comment 11"},{"id":"041c7c2d-0688-491e-b6cd-899eac95bd3d","pid":"","text":"comment 12"},{"id":"5acdf3ff-345b-47a5-bd66-a6687a1441b7","pid":"041c7c2d-0688-491e-b6cd-899eac95bd3d","text":"comment 13"},{"id":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","pid":"","text":"comment 14"},{"id":"6108b28c-a7af-4c5a-a38c-c22db0d34b31","pid":"aaee2ae5-7e3a-4435-a094-83bf6b77abfb","text":"comment 15"},{"id":"1736393e-95b0-4f5d-a149-50fe52c28350","pid":"","text":"comment 16"},{"id":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","pid":"1736393e-95b0-4f5d-a149-50fe52c28350","text":"comment 17"},{"id":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","pid":"b646f202-17aa-4af9-b8dc-c1d8ff3529ac","text":"comment 18"},{"id":"76e49597-6039-4cb5-a595-556ccc2e3c12","pid":"a8827b1d-fdbc-41c2-bdb5-38e8b308dedc","text":"comment 19"},{"id":"07dc4b90-65d3-4f75-8351-457305988235","pid":"76e49597-6039-4cb5-a595-556ccc2e3c12","text":"comment 20"},{"id":"2d4e838b-82df-4ca0-bf9b-f1dfb99d6763","pid":"07dc4b90-65d3-4f75-8351-457305988235","text":"comment 21"},{"id":"617c1760-0dca-409c-af2a-c614f0530e07","pid":"","text":"comment 22"},{"id":"712c0b7e-a9e4-40fd-ab78-c39b483b1435","pid":"617c1760-0dca-409c-af2a-c614f0530e07","text":"comment 23"},{"id":"e325094c-886e-42c9-bd59-fdd7a189b384","pid":"","text":"comment 24"},{"id":"f3b8b0f9-edef-4ee6-9555-42e8595f854c","pid":"e325094c-886e-42c9-bd59-fdd7a189b384","text":"comment 25"},{"id":"6e09a231-a2ee-4aa1-a898-57695e6fe153","pid":"","text":"comment 26"},{"id":"63e629d6-c0f9-4b36-ad96-e0c47cf8bb4e","pid":"6e09a231-a2ee-4aa1-a898-57695e6fe153","text":"comment 27"},{"id":"d7b698f1-8757-46db-a6e6-5141a481b42b","pid":"","text":"comment 28"},{"id":"a7e3d522-553c-44f1-befa-047bd94f0e59","pid":"","text":"comment 29"},{"id":"fe78ce24-c2c8-4d00-b96d-8b8be9ce0f06","pid":"","text":"comment 30"},{"id":"fabdccb5-a024-4476-bd51-7d55fb685c42","pid":"","text":"comment 31"},{"id":"608d0693-6e43-46a0-9e54-107da6adb109","pid":"fabdccb5-a024-4476-bd51-7d55fb685c42","text":"comment 32"}]` | |
var comments []Comment | |
err := json.Unmarshal([]byte(jsondata), &comments) | |
if err != nil { | |
panic(err) | |
} | |
arranged := ArrangeComments(comments) | |
arrangedjson, _ := json.MarshalIndent(arranged, "", " ") | |
fmt.Println(string(arrangedjson)) | |
fmt.Println("comments", len(comments), "arranged", recursiveCount(arranged)) | |
} | |
func recursiveCount(arranged []NestedComment) int { | |
count := len(arranged) | |
for _, item := range arranged { | |
count += recursiveCount(item.Children) | |
} | |
return count | |
} | |
// Nesting function ------------------------------------------------------------------------- | |
func ArrangeComments(comments []Comment) []NestedComment { | |
// Map to hold references to NestedComment by their ID | |
queue := make(map[string]*NestedComment) | |
// Result slice | |
var result []NestedComment | |
// First, create all NestedComments and store references in the map | |
for _, comment := range comments { | |
nc := &NestedComment{Comment: comment} | |
queue[comment.ID] = nc | |
} | |
// Second, loop through the map and add children to their parents | |
for _, comment := range queue { | |
if comment.ParentID != "" { | |
parent := queue[comment.Comment.ParentID] | |
if parent != nil { | |
parent.Children = append(parent.Children, *comment) | |
} | |
} | |
} | |
// Third, loop through the map and add all root comments to the result slice | |
for _, comment := range queue { | |
if comment.ParentID == "" { | |
result = append(result, *comment) | |
} | |
} | |
return result | |
} |
@MysteriousPotato you mean like this?
for _, comment := range queue {
if comment.ParentID != "" {
if queue[comment.Comment.ParentID] != nil {
queue[comment.Comment.ParentID].Children = append(queue[comment.Comment.ParentID].Children, *comment)
}
}
}
Same output, what am I doing wrong?
I mean using []*NestedComment
instead of []NestedComment
for storing children as pointers.
If you don't use pointers, any changes made to the children won't affect the child previously stored in its parent's children.
Ex.:
func main() {
type myStruct struct {
value int
}
test := myStruct{}
ptr := &test
ptr.value = 1
fmt.Println(test.value) // prints 1
// This will effectively create a copy of the value stored in `ptr`
// So any changes made to `ptr` won't affect `dereferenced` since it's a value copy, not a reference.
dereferenced := *ptr
ptr.value = 2
fmt.Println(dereferenced.value) // still prints 1
}
@MysteriousPotato that was it, thank you so much!
@MysteriousPotato do you have a BuyMeACoffee or something? I'd like to show my appreciation
That's very generous of you. I don't have a BuyMeACoffee but here's an idea:
You could donate to a charity of your choice! At the end, it's up to you. I'm just glad I could help.
@MysteriousPotato Great idea, I gave you a shout-out in my donation, thanks again!
@dlford 🎉 Great choice
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The issue is that you're dereferencing the
comment
ptr at line 68.This will have the effect of only storing the value of
comment
, not its reference.So when you append a comment to it's children later on, this change is not reflected on the value previously stored in its parent's
Children
.Using pointers to store the children should resolve the issue.