为了账号安全,请及时绑定邮箱和手机立即绑定

Golang:根据 id 和父 id 从线性数组创建嵌套

Golang:根据 id 和父 id 从线性数组创建嵌套

Go
www说 2022-11-23 10:17:54

我有一个名称的数据线性,例如:

  • 名称:一个,ID:1,ParentId:0

  • 名称:一对一,ID:2,ParentId:1

  • 名称:一对一,ID:3,ParentId:2

  • 名称:一一二,ID:4,ParentId:2

例如这个数据,我从数据库中获取,但我想测试我制作虚拟数据来构造的逻辑。我想我为数据递归地做了一个临时索引。如果地图中不存在数据,我会设置,如果数据必须附加到切片之前,我会得到索引。但是,我认为在函数递归中(我在下面显示),它不起作用(数据不附加)。为什么?有没有错误的算法逻辑?

我的结果的正确解决方案是什么

[

  {

    "id": 1,

    "name": "One",

    "children": [

      {

        "id": 2,

        "name": "One-One",

        "children": [

          {

            "id": 3,

            "name": "One-One-One",

            "children": null

          },

          {

            "id": 4,

            "name": "One-One-Two",

            "children": null

          }

        ]

      }

    ]

  }

]


golang 中的完整代码:


package main


import (

    "encoding/json"

    "fmt"

)


type Data struct {

    Id       int    `json:"id"`

    ParentId int    `json:"parent_id"`

    Name     string `json:"name"`

}


type Datas []Data


type Response struct {

    Id       int       `json:"id"`

    Name     string    `json:"name"`

    Children Responses `json:"children"`

}


type Responses []*Response


func main() {

    datas := Datas{

        {

            Name: "One",

            Id:   1,

        },

        {

            Name:     "One-One",

            Id:       2,

            ParentId: 1,

        },

        {

            Name:     "One-One-One",

            Id:       3,

            ParentId: 2,

        },

        {

            Name:     "One-One-Two",

            Id:       4,

            ParentId: 2,

        },

    }


    var result Responses

    tempIdx := make(map[int]int)


    for _, val := range datas {

        res := Response{

            Id:   val.Id,

            Name: val.Name,

        }


        if val.ParentId == 0 {

            result = append(result, &res)

            tempIdx[val.Id] = len(result) - 1

            continue

        } else {

            recursive(val.ParentId, result, res, tempIdx)

        }


    }


    json, err := json.Marshal(result)

    if err != nil {

        panic(err)

    }

    fmt.Println(string(json))

}


Golang Playground打开


查看完整描述

1 回答

?
阿晨1998

TA贡献1777条经验 获得超5个赞

切片不是数组

附加到函数中的切片不会增加原始切片的长度和容量。


change := func(slice []int) {

    slice = append(slice, 3)

}

slice := []int{1, 2}

change(slice)

fmt.Println(slice) 

// Output: [1 2]

无论如何,即使您解决了切片问题,您的输出也不会像预期的那样。您基本上使用的是树数据结构,因此建议使用一些树搜索算法。这是您使用BFS的工作示例


package main


import (

    "encoding/json"

    "fmt"

)


type Data struct {

    Id       int    `json:"id"`

    ParentId int    `json:"parent_id"`

    Name     string `json:"name"`

}


type Datas []Data


type Response struct {

    Id       int       `json:"id"`

    Name     string    `json:"name"`

    Children Responses `json:"children"`

}


type Responses []*Response


func main() {

    datas := Datas{

        {

            Name: "One",

            Id:   1,

        },

        {

            Name:     "One-One",

            Id:       2,

            ParentId: 1,

        },

        {

            Name:     "One-One-One",

            Id:       3,

            ParentId: 2,

        },

        {

            Name:     "One-One-Two",

            Id:       4,

            ParentId: 2,

        },

    }


    var result Responses

    for _, val := range datas {

        res := &Response{

            Id:   val.Id,

            Name: val.Name,

        }


        var found bool


        // iterate trough root nodes

        for _, root := range result {

            parent := findById(root, val.ParentId)

            if parent != nil {

                parent.Children = append(parent.Children, res)


                found = true

                break

            }

        }


        if !found {

            result = append(result, res)

        }

    }


    out, err := json.Marshal(result)

    if err != nil {

        panic(err)

    }

    fmt.Println(string(out))

}


func findById(root *Response, id int) *Response {

    queue := make([]*Response, 0)

    queue = append(queue, root)

    for len(queue) > 0 {

        nextUp := queue[0]

        queue = queue[1:]

        if nextUp.Id == id {

            return nextUp

        }

        if len(nextUp.Children) > 0 {

            for _, child := range nextUp.Children {

                queue = append(queue, child)

            }

        }

    }

    return nil

}



查看完整回答
反对 回复 6天前

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信