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

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 mainimport (    "encoding/json"    "fmt")type Data struct {    Id       int    `json:"id"`    ParentId int    `json:"parent_id"`    Name     string `json:"name"`}type Datas []Datatype Response struct {    Id       int       `json:"id"`    Name     string    `json:"name"`    Children Responses `json:"children"`}type Responses []*Responsefunc 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贡献2037条经验 获得超6个赞

切片不是数组

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


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

}



查看完整回答
反对 回复 2022-11-23
  • 1 回答
  • 0 关注
  • 79 浏览
慕课专栏
更多

添加回答

举报

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