From e1ceb06513807be766db6a693e65b0e6deebefbe Mon Sep 17 00:00:00 2001
From: jianggb <jianggb@miligc.com>
Date: Wed, 22 May 2024 12:35:58 +0800
Subject: [PATCH] fix: improve tree gen

---
 thinkgos/go.mod                  |  12 +++-
 thinkgos/go.sum                  |  25 ++++---
 thinkgos/leet_03/leet_03.go      | 120 ++++++++-----------------------
 thinkgos/leet_03/leet_03_test.go |  40 ++++-------
 4 files changed, 69 insertions(+), 128 deletions(-)

diff --git a/thinkgos/go.mod b/thinkgos/go.mod
index 7ce57b6..b9aa1ea 100644
--- a/thinkgos/go.mod
+++ b/thinkgos/go.mod
@@ -1,8 +1,14 @@
 module thinkgos
 
-go 1.16
+go 1.22
 
 require (
-	github.com/spf13/cast v1.3.1
-	github.com/stretchr/testify v1.7.0
+	github.com/spf13/cast v1.6.0
+	github.com/stretchr/testify v1.9.0
+)
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/thinkgos/go.sum b/thinkgos/go.sum
index 81a7a88..04e42ab 100644
--- a/thinkgos/go.sum
+++ b/thinkgos/go.sum
@@ -1,15 +1,22 @@
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
+github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/thinkgos/leet_03/leet_03.go b/thinkgos/leet_03/leet_03.go
index 48ceaab..ae5ff52 100644
--- a/thinkgos/leet_03/leet_03.go
+++ b/thinkgos/leet_03/leet_03.go
@@ -1,103 +1,43 @@
 package leet_03
 
-type Dept struct {
-	Id   int
-	Pid  int
-	Name string
-}
-
-type DeptTree struct {
-	*Dept
-	Children []DeptTree
-}
-
-func toDeptMap(rows []Dept) map[int][]*Dept {
-	mp := make(map[int][]*Dept)
-	for i := 0; i < len(rows); i++ {
-		v := &rows[i]
-		mp[v.Pid] = append(mp[v.Pid], v)
-	}
-	return mp
-}
-
-func toTree(rows []Dept, pid int) []DeptTree {
-	mp := toDeptMap(rows)
-	rt, ok := mp[pid]
-	if !ok || len(rt) == 0 {
-		return []DeptTree{}
-	}
-	root := make([]DeptTree, 0, len(rt))
-	for _, itm := range rt {
-		root = append(root, deepChildrenDept(mp, DeptTree{Dept: itm}))
+type Node interface {
+	GetId() int
+	GetPid() int
+	AppendChildren(Node)
+}
+
+func IntoTree[T Node](rows []T, rootPid int) []T {
+	var root []T
+	nodes := make(map[int]T, len(rows))
+	for _, v := range rows {
+		node := v
+		id := node.GetId()
+		pid := node.GetPid()
+		if pid == rootPid {
+			root = append(root, node)
+		} else if parent, exists := nodes[pid]; exists {
+			parent.AppendChildren(node)
+		}
+		nodes[id] = node
 	}
 	return root
 }
 
-func deepChildrenDept(mp map[int][]*Dept, itm DeptTree) DeptTree {
-	children, ok := mp[itm.Id]
-	if ok {
-		itm.Children = make([]DeptTree, 0, len(children))
-		for _, v := range children {
-			itm.Children = append(itm.Children, deepChildrenDept(mp, DeptTree{Dept: v}))
-		}
-	} else {
-		itm.Children = []DeptTree{}
-	}
-	return itm
+type Dept struct {
+	Id       int
+	Pid      int
+	Name     string
+	Children []*Dept
 }
 
-/**
-function toTree(arr, pid) {
-    let tree = [];
-    let hash = {};
-    arr.forEach((item) => {
-        const id = item.id;
-        item["children"] = hash[id] = [];
-        // 判断是否为父节点
-        if (item.pid === pid) {
-            tree.push(item);
-        } else {
-            const parentId = item.pid;
-            if (hash[parentId]) {
-                hash[parentId].push(item);
-            } else {
-                hash[parentId] = [];
-                hash[parentId].push(item);
-            }
-        }
-    });
-    console.log(hash)
-    return tree;
+func (d *Dept) GetId() int {
+	return d.Id
 }
-*/
 
-type DeptTree2 struct {
-	*Dept
-	Children *[]*DeptTree2
+func (d *Dept) GetPid() int {
+	return d.Pid
 }
 
-func toTree2(rows []Dept, pid int) []*DeptTree2 {
-	mp := make(map[int]*[]*DeptTree2) // 孩子
-	root := make([]*DeptTree2, 0, 10)
-	for i := 0; i < len(rows); i++ {
-		id := rows[i].Id
-		parentId := rows[i].Pid
-
-		dp := make([]*DeptTree2, 0)
-		mp[id] = &dp
-
-		entry := &DeptTree2{Dept: &rows[i], Children: &dp}
-		if parentId == pid {
-			root = append(root, entry)
-		} else {
-			v, ok := mp[parentId]
-			if ok {
-				*v = append(*v, entry)
-			} else {
-				dp = []*DeptTree2{entry}
-				mp[parentId] = &dp
-			}
-		}
-	}
-	return root
+func (d *Dept) AppendChildren(v Node) {
+	d.Children = append(d.Children, v.(*Dept))
 }
diff --git a/thinkgos/leet_03/leet_03_test.go b/thinkgos/leet_03/leet_03_test.go
index b09101a..9bc538c 100644
--- a/thinkgos/leet_03/leet_03_test.go
+++ b/thinkgos/leet_03/leet_03_test.go
@@ -7,40 +7,28 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-var arr = []Dept{
-	{1, 0, "超然科技"},
-	{2, 0, "低速科技"},
-	{3, 1, "科研中心"},
-	{4, 1, "运营中心"},
-	{5, 2, "吃喝院"},
-	{6, 2, "研究院"},
-	{7, 3, "aa"},
-	{8, 3, "bb"},
-	{9, 4, "cc"},
-	{10, 5, "dd"},
-	{11, 6, "ee"},
+var arr = []*Dept{
+	{1, 0, "超然科技", nil},
+	{2, 0, "低速科技", nil},
+	{3, 1, "科研中心", nil},
+	{4, 1, "运营中心", nil},
+	{5, 2, "吃喝院", nil},
+	{6, 2, "研究院", nil},
+	{7, 3, "aa", nil},
+	{8, 3, "bb", nil},
+	{9, 4, "cc", nil},
+	{10, 5, "dd", nil},
+	{11, 6, "ee", nil},
 }
 
 func TestTree(t *testing.T) {
-	v, err := json.MarshalIndent(toTree(arr, 0), " ", "  ")
+	v, err := json.MarshalIndent(IntoTree(arr, 0), " ", "  ")
 	require.NoError(t, err)
 	t.Logf(string(v))
 }
 
 func BenchmarkTree(b *testing.B) {
 	for i := 0; i < b.N; i++ {
-		toTree(arr, 0)
-	}
-}
-
-func TestTree2(t *testing.T) {
-	v, err := json.MarshalIndent(toTree2(arr, 0), " ", "  ")
-	require.NoError(t, err)
-	t.Logf(string(v))
-}
-
-func BenchmarkTree2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		toTree2(arr, 0)
+		IntoTree(arr, 0)
 	}
 }