2017-08-27 32 views
-1

私は再帰的な構造体を使いこなしています。しかし、私はこれにどのように接近する適切な方法があるか分かりません。複数の構造体を同じものに結合する方法

私が意味することをさらに説明するために、以下のコードスニペットを含めました。

package main 

import "fmt" 

type Container struct { 
    F   int 
    Collection []SubContainer 
} 

type SubContainer struct { 
    Key string 
    Value int 
} 

func main() { 
    commits := map[string]int{ 
     "a": 1, 
     "b": 2, 
     "c": 3, 
     "d": 4, 
    } 

    sc := []SubContainer{} 
    c := []Container{} 
    count := 0 

    for k, v := range commits { 
     sc = append(sc, SubContainer{Key: k, Value: v}) 
     count++ 

     if len(sc) == 2 { 
      c = append(c, Container{Collection: sc, F: count}) 
      sc = nil 
     } 
    } 

    for _, r := range c { 
     fmt.Println(r) 
    } 
} 

結果:

{2 [{a 1} {b 2}]} 
{4 [{c 3} {d 4}]} 

望ましい結果:

{6 {2 [{a 1} {b 2}]} {4 [{c 3} {d 4}]}} 

遊び場リンク:私の周り私の頭をラップトラブルを抱えているhttps://play.golang.org/p/j6rbhgcOoT

1つの警告があるcommits長さという変更される可能性があります(私は当初、差分t親構造体)。任意の提案をいただければ幸いです...再帰的な構造体でこれを行うには、これを達成するための正しいアプローチが必要ですか?ありがとう!

+1

'F'がここにどのような役割を果たしていますか?スライスの長さだけの場合は、それをメソッドで計算してみませんか?また、あなたの望む結果が何を表しているのかも不明です。 'if len(sc)== 2'という特殊なケースはなぜですか?ここでは6,2,4が何を表していますか(1,2,3,4とどのように関係していますか)?あなたは再帰をしたいと言いますが、あなたのタイプに再帰はありません。 Goの再帰的なデータ構造の例については、https://stackoverflow.com/questions/37366219/golang-recursive-data-structures#37366490を参照してください。 –

答えて

0

正確な目標を確認せずに目的の出力に近づけようとしましたが、あなたが提供したスニペットの修正版があります。

コレクションでString() stringメソッドを使用して、フォーマットをカスタマイズできます。

package main 

import "fmt" 

type ContainerCollection struct { 
    Count int 
    List []Container 
} 

func (cc ContainerCollection) String() string { 
    total := 0 
    for _, c := range cc.List { 
     total += c.F 
    } 
    return fmt.Sprintf("{%d %v}", total, cc.List) 
} 

type Container struct { 
    F   int 
    Collection []SubContainer 
} 

type SubContainer struct { 
    Key string 
    Value int 
} 

func main() { 
    commits := map[string]int{ 
     "a": 1, 
     "b": 2, 
     "c": 3, 
     "d": 4, 
    } 

    c := ContainerCollection{Count: 0} 
    sc := []SubContainer{} 

    for k, v := range commits { 
     sc = append(sc, SubContainer{Key: k, Value: v}) 
     c.Count++ 
     if len(sc) == 2 { 
      c.List = append(c.List, Container{Collection: sc, F: c.Count}) 
      sc = []SubContainer{} 
     } 
    } 
    // Should also cover odd number of commits 
    if len(sc) != 0 { 
     c.Count++ 
     c.List = append(c.List, Container{Collection: sc, F: c.Count}) 
    } 

    // for _, r := range c.List { fmt.Println(r) } 

    fmt.Println(c) 
} 

結果:

{6 [{2 [{a 1} {b 2}]} {4 [{c 3} {d 4}]}]} 

Playground

0

ここにあなたのコードに最小限の変更で何かが(ちょうど基本的に要約構造体である 'スーパー' の容器を、追加しました)。おそらくこれは、これが別のライブラリ/パッケージ/ネットなどに渡されている場合にのみ必要です。そうでなければ、totalCountを維持するだけで十分かもしれません。

package main 

import "fmt" 

type SuperContainer struct { 
    TotalCount int 
    Containers []Container 
} 

type Container struct { 
    F   int 
    Collection []SubContainer 
} 

type SubContainer struct { 
    Key string 
    Value int 
} 

func main() { 
    var totalCount int 
    commits := map[string]int{ 
     "a": 1, 
     "b": 2, 
     "c": 3, 
     "d": 4, 
    } 

    sc := []SubContainer{} 
    c := []Container{} 
    count := 0 

    for k, v := range commits { 
     sc = append(sc, SubContainer{Key: k, Value: v}) 
     count++ 

     if len(sc) == 2 { 
      totalCount += count 
      c = append(c, Container{Collection: sc, F: count}) 
      sc = nil 
     } 
    } 

    for _, r := range c { 
     fmt.Println(r) 
    } 
    supC := SuperContainer{TotalCount: totalCount, Containers: c} 
    fmt.Println(supC) 
} 

遊び場:https://play.golang.org/p/yN3N3gHaCX

関連する問題