feat: 增加将列表数据转换为树形结构的能力
This commit is contained in:
@ -7,7 +7,9 @@
|
|||||||
// Date : 2025-11-25 11:30
|
// Date : 2025-11-25 11:30
|
||||||
package op_array
|
package op_array
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// ToMap 数组转map
|
// ToMap 数组转map
|
||||||
func ToMap[Key comparable, Value any](dataList []Value, keyFormat func(item Value) Key) map[Key]Value {
|
func ToMap[Key comparable, Value any](dataList []Value, keyFormat func(item Value) Key) map[Key]Value {
|
||||||
@ -68,3 +70,45 @@ func Group[Key comparable, Value any](dataList []Value, keyFormat func(item Valu
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TreeItem 数据结构
|
||||||
|
type TreeItem[ID comparable, Value any] struct {
|
||||||
|
ID ID `json:"id" dc:"数据ID"`
|
||||||
|
ParentID ID `json:"parent_id" dc:"父级ID"`
|
||||||
|
Value Value `json:"value" dc:"数据值"`
|
||||||
|
ChildList []*TreeItem[ID, Value] `json:"child_list" dc:"子级数据列表"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tree 将列表数据转为属性结构
|
||||||
|
func Tree[ID comparable, Value any](dataList []Value, formatParentID func(v Value) ID, formatID func(v Value) ID) *TreeItem[ID, Value] {
|
||||||
|
// list 转table
|
||||||
|
dataTable := make(map[ID]*TreeItem[ID, Value])
|
||||||
|
for _, item := range dataList {
|
||||||
|
dataID := formatID(item)
|
||||||
|
dataTable[dataID] = &TreeItem[ID, Value]{
|
||||||
|
ID: dataID,
|
||||||
|
ParentID: formatParentID(item),
|
||||||
|
Value: item,
|
||||||
|
ChildList: make([]*TreeItem[ID, Value], 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 构建树(保证一定是一棵树)
|
||||||
|
rootData := &TreeItem[ID, Value]{
|
||||||
|
ID: *new(ID),
|
||||||
|
ParentID: *new(ID),
|
||||||
|
Value: *new(Value),
|
||||||
|
ChildList: make([]*TreeItem[ID, Value], 0), // 子数据列表
|
||||||
|
}
|
||||||
|
for _, item := range dataList {
|
||||||
|
dataID := formatID(item)
|
||||||
|
parentID := formatParentID(item)
|
||||||
|
if _, exist := dataTable[parentID]; exist {
|
||||||
|
// 归属某一个父级节点
|
||||||
|
dataTable[parentID].ChildList = append(dataTable[parentID].ChildList, dataTable[dataID])
|
||||||
|
} else {
|
||||||
|
// 部署于任何父节点, 则归属于虚拟的根节点
|
||||||
|
rootData.ChildList = append(rootData.ChildList, dataTable[dataID])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rootData
|
||||||
|
}
|
||||||
|
|||||||
34
op_array/util_test.go
Normal file
34
op_array/util_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Package op_array ...
|
||||||
|
//
|
||||||
|
// Description : op_array ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-11-27 12:40
|
||||||
|
package op_array
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTree(t *testing.T) {
|
||||||
|
type Data struct {
|
||||||
|
ID int `json:"id" dc:"数据ID"`
|
||||||
|
ParentID int `json:"parent_id" dc:"父级ID"`
|
||||||
|
Value string `json:"value" dc:"数据值"`
|
||||||
|
}
|
||||||
|
|
||||||
|
dataList := []Data{
|
||||||
|
{ID: 1, ParentID: 0, Value: "1"},
|
||||||
|
{ID: 2, ParentID: 1, Value: "2"},
|
||||||
|
{ID: 3, ParentID: 1, Value: "3"},
|
||||||
|
{ID: 4, ParentID: 2, Value: "4"},
|
||||||
|
{ID: 5, ParentID: 2, Value: "5"},
|
||||||
|
{ID: 6, ParentID: 3, Value: "6"},
|
||||||
|
{ID: 7, ParentID: 3, Value: "7"},
|
||||||
|
}
|
||||||
|
res := Tree(dataList, func(v Data) int { return v.ParentID }, func(v Data) int { return v.ID })
|
||||||
|
serialize.JSON.ConsoleOutput(res)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user