From b0d0a6db285ec1638ff91720354a0ad1772eb61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Thu, 27 Nov 2025 12:44:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=B0=86=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2=E4=B8=BA=E6=A0=91?= =?UTF-8?q?=E5=BD=A2=E7=BB=93=E6=9E=84=E7=9A=84=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- op_array/util.go | 46 ++++++++++++++++++++++++++++++++++++++++++- op_array/util_test.go | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 op_array/util_test.go 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) +}