2016-10-20 4 views
0

私は深さが不明なデータベースからカテゴリのリストを取得しようとしています。 map[int][]interface{}を使って可能ですか、それはまったく可能ですか?Goの未知の深さリスト

ベスト出力は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逃げ道。 –

関連する問題