2016-10-20 6 views
0

알 수없는 수준의 데이터베이스에서 카테고리 목록을 가져 오려고합니다. map[int][]interface{}을 사용하는 것이 가능합니까?Go에 알 수없는 깊이 목록

type Category struct { 
    ID  int 
    Name  string 
    ParentID int 
} 

func GetCategories(db *gorm.DB) map[int][]interface{} { 
    var result = make(map[int][]interface{}) 
    var categories = []Category{} 
    db.Where("parent_id = ?", 0).Find(&categories) 
    for len(categories) > 0 { 
     var ids []int 
     for _, cat := range categories { 
      ids = append(ids, cat.ID) 
      if cat.ParentID == 0 { 
       result[cat.ID] = append(result[cat.ID], cat) 
      } else { 

       // This work only for 2nd level ... 
       result[cat.ParentID] = append(result[cat.ParentID], cat) 
      } 
     } 
    } 
    return result 
} 

최상의 출력은 JSON 배열에 있습니다. 예를 들어 :

[ 
    {id: 1, name: "Car", Parent: 0, Children: []}, 
    {id: 2, name: "Boat", Parent: 0, Children: [ 
     {id: 4, name: "Fast", Parent: 2, Children: []}, 
     {id: 5, name: "Slow", Parent: 2, Children: [ 
      {id: 6, name: "ExtraSlow", Parent: 5, Children: []}, 
     ]}, 
    ]}, 
    {id: 3, name: "Rocket", Parent: 0, Children: []} 
] 
+1

가능하지만 피해야합니다. 찾고자하는 타입은'map [int] interface {}'입니다. –

+0

질문을 2/3 수준의 예제 출력으로 업데이트 할 수 있습니까? –

답변

0

해결책을 찾았습니다! 카테고리 구조체 안에 카테고리 조각을 추가하고 [depth][]Categories{}에 저장된 데이터베이스에서 각 레이어의 깊이를 요청합니다. 마지막으로 모든 데이터를 아래에서 위로 정렬합니다.

type Category struct { 
    ID  int 
    Name  string 
    ParentID int 
    Children []Category 
} 

func GetCategories(db *gorm.DB) []Category { 

    // Request data from database 
    var categories = []Category{} 
    var store = [][]Category{} 
    db.Where("parent_id = ?", 0).Find(&categories) 
    for len(categories) > 0 { 
     var ids []int 
     for _, cat := range categories { 
      ids = append(ids, cat.ID) 
     } 
     store = append(store, categories) 
     categories = []Category{} 
     db.Where("parent_id in (?)", ids).Find(&categories) 
    } 

    // Sort and move children to parent 
    lastLayer := len(store) - 1 
    for lastLayer >= 0 { 
     if (lastLayer - 1 >= 0) { 
      for _, child := range store[lastLayer] { 
       for i, parent := range store[lastLayer -1] { 
        if parent.ID == child.ParentID { 
         store[lastLayer -1][i].Children = append(store[lastLayer -1][i]. 
          Children, child) 
        } 
       } 
      } 
     } 
     lastLayer--; 
    } 

    return store[0] 
} 

// Return content as JSON response in WebApp 
func Output(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Content-Type", "application/json") 
    json.NewEncoder(w).Encode(GetCategories(databaseConnection)) 
} 
0

당신은지도의 기본 레벨의 모든 멤버를 저장하고 다음의 모든 목록 어린이 있어야합니다.

그런 다음 배열 ids과 같은 방법으로 맵을 사용할 수 있습니다.

func GetCategories(db *gorm.DB) map[int][]interface{} { 
    var result = make(map[int][]interface{}) 
    var categories = []Category{} 
    db.Where("parent_id = ?", 0).Find(&categories) 
    if len(categories) > 0 { 
     for _, cat := range categories { 
      if _, ok := result[cat.ID]; !ok { 
       result[cat.ID] = make([]interface{}, 0, 5) 
      } 

      if cat.ParentID != 0 { 
       if _, ok := result[cat.ParentID]; !ok { 
        result[cat.ParentID] = make([] interface{}, 0, 5) 
       } 
       result[cat.ParentID] = append(result[cat.ParentID], cat)     
      } 
     } 
    } 
    return result 
} 

그것은 당신이 원하는 것을 정확하게 명확하지 그러나 이것은 당신의 모든 범주를 저장하는 재귀 적 데이터 구조에 대한 필요성을 제거지도의 항목을 "0"의 모든 부모를 둘 것이다.

+0

결과에서이 코드를 컴파일 할 때 오류가 발생합니다. [cat.ParentID] = append (result [cat.ParentID], cat) – Kroksys

+0

오류 : 'append의 첫 번째 인수는 slice 여야합니다. have interface {}' – Kroksys

+0

죄송합니다. 실수로 미안 해요, 대답을 편집했습니다. 당신은'result [cat.ID] = make ([] category, 0, 5)'를'result [cat.ID] = make ([] interface {}, 0, 5)'로 변경 한 다음 assertion on을 입력해야합니다. 탈출구. –