2014-04-09 2 views
3

테이블에서 나무를 만들고 싶습니다. 표는 다음과 같습니다 :golang을 사용하여 테이블에서 트리를 만드시겠습니까?

OrgID OrgName  parentID 
A001 Dept   0 -----th top 
A002 subDept1  A001 
A003 sub_subDept A002 
A006 gran_subDept A003 
A004 subDept2  A001 

을하고 난 결과가 이동 사용하여 작업을 수행하는 방법을, 다음과 같습니다 원하는 : 무엇을 해결할 수, 귀하의 질문과 의견에 제공된 정보와

 
Dept 

--subDept1 

----sub_subDept 

------gran_subDept 

--subDept2 
+0

더 구체적으로 테이블의 종류; MySQL의 테이블? [] 조직 슬라이스? mongoDB 컬렉션? 그리고 나무에 어떤 유형을 넣으시겠습니까? – ANisus

+0

테이블은 mysql의 슬라이스입니다. – user3373877

답변

4

당신이 트리 구조로 라인을 구문 분석하려면이 그것을 할 수있는 방법은 다음과 같습니다

package main 

import (
    "bufio" 
    "fmt" 
    "io" 
    "os" 
    "strings" 
) 

type Node struct { 
    name  string 
    children []*Node 
} 

var (
    nodeTable = map[string]*Node{} 
    root  *Node 
) 

func add(id, name, parentId string) { 
    fmt.Printf("add: id=%v name=%v parentId=%v\n", id, name, parentId) 

    node := &Node{name: name, children: []*Node{}} 

    if parentId == "0" { 
     root = node 
    } else { 

     parent, ok := nodeTable[parentId] 
     if !ok { 
      fmt.Printf("add: parentId=%v: not found\n", parentId) 
      return 
     } 

     parent.children = append(parent.children, node) 
    } 

    nodeTable[id] = node 
} 

func scan() { 
    input := os.Stdin 
    reader := bufio.NewReader(input) 
    lineCount := 0 
    for { 
     lineCount++ 
     line, err := reader.ReadString('\n') 
     if err == io.EOF { 
      break 
     } 
     if err != nil { 
      fmt.Printf("error reading lines: %v\n", err) 
      return 
     } 
     tokens := strings.Fields(line) 
     if t := len(tokens); t != 3 { 
      fmt.Printf("bad input line %v: tokens=%d [%v]\n", lineCount, t, line) 
      continue 
     } 
     add(tokens[0], tokens[1], tokens[2]) 
    } 
} 

func showNode(node *Node, prefix string) { 
    if prefix == "" { 
     fmt.Printf("%v\n\n", node.name) 
    } else { 
     fmt.Printf("%v %v\n\n", prefix, node.name) 
    } 
    for _, n := range node.children { 
     showNode(n, prefix+"--") 
    } 
} 

func show() { 
    if root == nil { 
     fmt.Printf("show: root node not found\n") 
     return 
    } 
    fmt.Printf("RESULT:\n") 
    showNode(root, "") 
} 

func main() { 
    fmt.Printf("main: reading input from stdin\n") 
    scan() 
    fmt.Printf("main: reading input from stdin -- done\n") 
    show() 
    fmt.Printf("main: end\n") 
} 
+0

좋다! 또 다른 좋은 방법. – user3373877

3

귀하의 문제는 일반적인 재귀 루프입니다.

package main 

import "fmt" 

type Org struct { 
    OrgID string 
    OrgName string 
    parentID string 
} 

func printTree(tbl []Org, parent string, depth int) { 
    for _, r := range tbl { 
     if r.parentID == parent { 
      for i := 0; i < depth; i++ { 
       fmt.Print("--") 
      } 
      fmt.Print(r.OrgName, "\n\n") 
      printTree(tbl, r.OrgID, depth+1) 
     } 
    } 
} 

func main() { 
    data := []Org{ 
     {"A001", "Dept", "0 -----th top"}, 
     {"A002", "subDept1", "A001"}, 
     {"A003", "sub_subDept", "A002"}, 
     {"A006", "gran_subDept", "A003"}, 
     {"A004", "subDept2", "A001"}, 
    } 

    printTree(data, "0 -----th top", 0) 
} 

결과 :

Dept 

--subDept1 

----sub_subDept 

------gran_subDept 

--subDept2 

놀이터 :http://play.golang.org/p/27CQAhI8gf

는 부모가 자신의 자손 인 경우이 재귀 기능을 넣다 거기 루프에 갇혀 얻을 수 있음에 유의 어린이.

+0

우수! 결과를 json으로 출력하는 방법은 무엇입니까? – user3373877

+0

json에서 결과를 얻으려면 원하는 json 구조를 질문에 추가해야합니다. 여러 가지 방법으로 그 결과를 나타낼 수 있습니다. – ANisus

+0

@ user3373877 "위로"화살표를 클릭하여 좋아하는 답변에 upvote를 전송할 수 있다는 것을 알고 계십니까? – Everton

관련 문제