diff --git a/op_array/util.go b/op_array/util.go index 118abd1..e7c1da7 100644 --- a/op_array/util.go +++ b/op_array/util.go @@ -7,7 +7,9 @@ // Date : 2025-11-25 11:30 package op_array -import "fmt" +import ( + "fmt" +) // ToMap 数组转map 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 } + +// 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 +} diff --git a/op_array/util_test.go b/op_array/util_test.go new file mode 100644 index 0000000..7c057cf --- /dev/null +++ b/op_array/util_test.go @@ -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) +}