Maybe its just late in the day and this is making my brain melt.
I'm trying to convert a flat list of nested sets into a multi-dimensional nested array.
I have a bunch of structured CMS entries as follows:
entries := []TreeEntry{
{
Slug: "about-us",
Title: "About us",
Left: 2,
Right: 11,
Level: 1,
},
{
Slug: "more-about-us",
Title: "More about us",
Left: 3,
Right: 6,
Level: 2,
},
{
Slug: "even-more-about-us",
Title: "Even more about us",
Left: 4,
Right: 5,
Level: 3,
},
{
Slug: "contact-us",
Title: "Contact us",
Left: 2,
Right: 7,
Level: 1,
},
}
And I want to unflatten them as follows:
entries := []TreeEntry{
{
Slug: "about-us",
Title: "About us",
Left: 2,
Right: 11,
Level: 1,
Children: []TreeEntry{
{
Slug: "more-about-us",
Title: "More about us",
Left: 3,
Right: 6,
Level: 2,
Children: []TreeEntry{
{
Slug: "even-more-about-us",
Title: "Even more about us",
Left: 4,
Right: 5,
Level: 3,
},
},
},
},
},
{
Slug: "contact-us",
Title: "Contact us",
Left: 2,
Right: 7,
Level: 1,
},
}
The aim here is ultimately to return a menu structure with the slugs contact'ed together as appropriate, but some reason, I just cannot get my head around achieving this in Go.
Can anybody point me in the correct direction?
Edit: Added non-working example of what I've attempted:
https://play.golang.org/p/oKWo21lu__7
The results never add below the first level.
Thanks, J
As it turns out, I needed to use pointers to hold the child entries. The following setup works:
type TreeEntry struct {
Id int64 `db:"elementId" json:"id"`
Slug string `db:"slug" json:"slug"`
Title string `db:"title" json:"title"`
Left int `db:"lft" json:"-"`
Right int `db:"rgt" json:"-"`
Level int `db:"level" json:"-"`
Children []*TreeEntry `json:"children"`
}
func (t *TreeEntry) AddNestedChild(newEntry TreeEntry) {
// If this child is one level below the current node, just add it here for now
if newEntry.Level == t.Level+1 {
t.Children = append(t.Children, &newEntry)
} else {
// Loop through the children and see if it fits anywhere
for _, child := range t.Children {
if newEntry.Left > child.Left && newEntry.Right < child.Right {
child.AddNestedChild(newEntry)
break
}
}
}
}