在GO中递归地检索ID的片段

huangapple go评论67阅读模式
英文:

Retrieve a slice of IDs recursively in GO

问题

type MenuItem struct {
    Id          int32
    Type        string
    SortOrder   int8
    CategoryId  int32
    Children    []*MenuItem
}

func getCategoryIds(menuItems []*MenuItem) []int32 {
    var categoryIds []int32
    for _, menuItem := range menuItems {
        categoryIds = append(categoryIds, menuItem.CategoryId)
        if len(menuItem.Children) > 0 {
            categoryIds = append(categoryIds, getCategoryIds(menuItem.Children)...)
        }
    }
    return categoryIds
}

func main() {
    menuItems := []MenuItem{
        {
            Id:         1,
            Type:       "type1",
            SortOrder:  1,
            CategoryId: 11,
            Children: []*MenuItem{
                {
                    Id:         2,
                    Type:       "type2",
                    SortOrder:  2,
                    CategoryId: 12,
                    Children: []*MenuItem{
                        {
                            Id:         3,
                            Type:       "type3",
                            SortOrder:  3,
                            CategoryId: 13,
                            Children:   nil,
                        },
                    },
                },
                {
                    Id:         4,
                    Type:       "type4",
                    SortOrder:  4,
                    CategoryId: 14,
                    Children: []*MenuItem{
                        {
                            Id:         5,
                            Type:       "type5",
                            SortOrder:  5,
                            CategoryId: 15,
                            Children:   nil,
                        },
                    },
                },
            },
        },
        {
            Id:         6,
            Type:       "type6",
            SortOrder:  6,
            CategoryId: 16,
            Children: []*MenuItem{
                {
                    Id:         7,
                    Type:       "type7",
                    SortOrder:  7,
                    CategoryId: 17,
                    Children: []*MenuItem{
                        {
                            Id:         8,
                            Type:       "type8",
                            SortOrder:  8,
                            CategoryId: 18,
                            Children:   nil,
                        },
                    },
                },
                {
                    Id:         9,
                    Type:       "type9",
                    SortOrder:  9,
                    CategoryId: 19,
                    Children: []*MenuItem{
                        {
                            Id:         10,
                            Type:       "type10",
                            SortOrder:  10,
                            CategoryId: 20,
                            Children:   nil,
                        },
                    },
                },
            },
        },
    }

    categoryIds := getCategoryIds(menuItems)
    fmt.Println(categoryIds)
}

这段代码定义了一个 MenuItem 结构体,其中包含了 IdTypeSortOrderCategoryIdChildren 字段。为了获取仅包含 CategoryId 值的切片,我们可以使用递归的方式来处理 Children 字段。通过遍历 menuItems 切片,将每个 MenuItemCategoryId 值添加到 categoryIds 切片中,并且如果该 MenuItemChildren 不为空,则递归调用 getCategoryIds 函数来处理子菜单项。最后,返回 categoryIds 切片。

main 函数中,我们创建了一个示例的 menuItems 切片,并调用 getCategoryIds 函数来获取仅包含 CategoryId 值的切片。最后,将结果打印输出。

英文:
type MenuItem struct {
		Id              int32       
		Type            string           
		SortOrder       int8        
		CategoryId      int32   
		Children        []*MenuItem 
	}

If you have this struct, and you have a slice of []MenuItem. I would like to retrieve a slice only with CategoryId values. This looks like a recursive use case due to the Children but based on how append function for slices works, it looks a bit tricky. Any ideas? How would you do it?

The end result should be a slice of []int32: [11, 1900, 12, 1300,...., 2090]

答案1

得分: 3

append为您完成繁重的工作,处理内存扩展,并在每个递归步骤中返回其结果:

func traverse(m *MenuItem) (r []int32) {

    if m == nil {
        return
    }

    r = append(r, m.CategoryId)

    for _, c := range m.Children {
        r = append(r, traverse(c)...)
    }

    return
}

链接:https://go.dev/play/p/8d0cyPMV0r6

英文:

Let append do the hard work for you, handling memory expansion, and return its result during each recursive step:

func traverse(m *MenuItem) (r []int32) {
if m == nil {
return
}
r = append(r, m.CategoryId)
for _, c := range m.Children {
r = append(r, traverse(c)...)
}
return
}

https://go.dev/play/p/8d0cyPMV0r6

huangapple
  • 本文由 发表于 2022年8月29日 20:55:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/73529128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定