父子關係結構梳理(Golang實現)
練練Golang,把一個資料庫表中常用的兩列父子關係結構(如下表)梳理成了目錄形式:
P C------------A | A1A | A2A1 | A11A2 | A21A2 | A22... | ...
發現所用代碼比Python版多了30%。
順便談談對Golang的感覺,Golang的開發哲學還是比較獨樹一幟的,比如為啥沒有參數默認值、泛型等,都有它自己的理解;而它的一些語法,如結構體、介面、panic設計、命名返回等,也是比較另闢蹊徑,剛開始確實有個熟悉及適應的過程。
遵循「Simplify only after the function is correct」,先把功能實現了,以後把Golang理解得更加透徹了、更有Go味兒了,再回頭審視一下。
附上Golang代碼:
package mainimport ( "fmt" "strings")type node struct { name string child []*node}func getTopElements(o [][2]string, fn func([]string, string) bool) (t []string, anyLuck bool) { for _, elem1 := range o { isFound := false for _, elem2 := range o { if elem1[0] == elem2[1] { isFound = true break } } if !isFound { anyLuck = true if !fn(t, elem1[0]) { t = append(t, elem1[0]) } } } return}func seek(root *node, origin [][2]string) { searchingNode := root.child for { endFlag := true tmpNode := []*node{} for _, item := range searchingNode { for _, o := range origin { if item.name == o[0] { endFlag = false item.child = append(item.child, &node{name: o[1]}) } } for _, child := range item.child { tmpNode = append(tmpNode, child) } } if endFlag { break } else { searchingNode = tmpNode } }}func genPrintTree(n *node, indent int, s []string) []string { for _, item := range n.child { s = genPrintTree(item, indent+1, s) } s = append(s, strings.Repeat(" ", indent-1)+" ."+n.name) return s}func printTree(n *node, indent int, s []string) { sc := genPrintTree(n, indent, s) for idx := range sc { fmt.Printf("%v
", sc[len(sc)-1-idx]) }}func main() { origin := [][2]string{ {"A112", "A1122"}, {"A", "A1"}, {"A", "A2"}, {"A1", "A11"}, {"A2", "A21"}, {"A2", "A22"}, {"A", "A3"}, {"A22", "A221"}, {"A11", "A111"}, {"A21", "A211"}, {"A11", "A112"}, {"A21", "A212"}, {"A11", "A113"}, {"A112", "A1121"}, {"A3", "A31"}, {"A31", "A311"}, {"A22", "A222"}, {"A31", "A312"}, {"A31", "A313"}, {"A311", "A3111"}, {"A312", "A3121"}, {"A3111", "A31111"}, {"B", "B1"}, {"B", "B2"}, {"B2", "B21"}, {"C", "C1"}, {"C1", "C11"}, {"C11", "C111"}, {"C11", "C112"}, {"C112", "C1121"}, {"C1121", "C11211"}, {"C11", "C113"}, {"C11211", "C112111"}, {"C112111", "C1121111"}, {"B21", "B211"}, {"C", "C2"}, {"C2", "C21"}, {"C21", "C22"}, {"C", "C3"}, {"B1", "B11"}} root := &node{name: "root"} if topElements, anyLuck := getTopElements(origin, func(t []string, e string) (isExist bool) { for _, item := range t { if item == e { isExist = true break } } return }); anyLuck { for _, item := range topElements { root.child = append(root.child, &node{name: item}) } seek(root, origin) } printTree(root, 1, []string{})}
運行結果:
.root .C .C3 .C2 .C21 .C22 .C1 .C11 .C113 .C112 .C1121 .C11211 .C112111 .C1121111 .C111 .B .B2 .B21 .B211 .B1 .B11 .A .A3 .A31 .A313 .A312 .A3121 .A311 .A3111 .A31111 .A2 .A22 .A222 .A221 .A21 .A212 .A211 .A1 .A11 .A113 .A112 .A1121 .A1122 .A111
繼續Golang之旅——並發。
我的個人主頁:http://www.2gua.info
推薦閱讀:
※推薦三個很贊的英語學習網站
※用 ConstraintLayout 和 ConstraintSet 實現 Android 關鍵幀動畫
※Flyme 6 同時基於安卓 5.1 和安卓 6.0 在編程方面不會更難嗎?
※【編程之外】從《海賊王》的視角走進BAT的世界