扁平嵌套设置为Go中的嵌套结构

时间:2018-01-31 17:59:55

标签: go nested-sets

也许就在当天晚些时候,这让我的大脑融化了。

我试图将嵌套集的平面列表转换为多维嵌套数组。

我有一堆结构化的CMS条目如下:

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,
        },
    }

我想按照以下方式解决这些问题:

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,
        },
    }

这里的目标最终是返回一个菜单结构,并将slug联系在一起,但有些原因,我只是无法在Go中实现这一目标。

有人能指出我正确的方向吗?

编辑:添加了我尝试过的非工作示例:

https://play.golang.org/p/oKWo21lu__7

结果永远不会低于第一级。

谢谢, Ĵ

1 个答案:

答案 0 :(得分:0)

事实证明,我需要使用指针来保存子条目。以下设置有效:

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
            }
        }
    }
}