2017-08-01 21 views
0

小さなヘルパー関数を作成して、大きな配列のアイテムを最大サイズがnの小さな配列に分割しました。汎用ヘルパー関数を作成する

func toPackages(e []int, n int) [][]int { 
    var p [][]int 
    packets := int(math.Ceil(float64(len(e))/float64(n))) 
    for i := 0; i < packets; i++ { 
     start := i * n 
     end := n * (i + 1) 
     if len(e) < end { 
      end = len(e) 
     } 
     p = append(p, e[start:end]) 
    } 
    return p 
} 

Golang Playgroundでの作業例。
私は分割したいいくつかの異なるタイプの配列を持っています。私はそれをinterface{}とのインターフェイスを使って変換しようとしました。

+0

goにはジェネリックはありません。 'interface {}'を使うか、この特定の関数を実行するために必要な型ごとに関数を作成することができます。 – Adrian

答えて

3

これをうまく処理するための汎用機能を作るのはかなり難しいです。 []intから[]interface{}に変換してスニペットをコピーするだけなので、多くのコードを費やすことがあります。でも、私はそれを行うには、わずかによりよい方法があります:のみ変更することにより

func splitStrings(src []string, n int) (p [][]string){ 
    for len(src) > n{ 
     p = append(p,src[:n]) 
     src = src[n:] 
    } 
    if(len(src) > 0){ 
     p = append(p,src) 
    } 
    return p 
} 

playground link

func splitInts(src []int, n int) (p [][]int){ 
    for len(src) > n{ 
     p = append(p,src[:n]) 
     src = src[n:] 
    } 
    if(len(src) > 0){ 
     p = append(p,src) 
    } 
    return p 
} 

ので、種類の機能の変更には何も、それが簡単にコピーすることができます最初の行

0

一般的に、必要なすべてのタイプの関数を書き込むことをお勧めします。これはスピードの問題でもあります。リフレクトを使用して汎用関数を記述すると、それほど速くはありません。

あなたはまだここに、一般的な機能が必要な場合には、次のとおりです。

func genToPackages(e interface{}, n int) interface{} { 
    t := reflect.TypeOf(e) 
    if t.Kind() != reflect.Slice { 
     log.Println("e has to be a slice") 
    } 
    v := reflect.ValueOf(e) 

    packets := int(math.Ceil(float64(v.Len())/float64(n))) 
    p := reflect.MakeSlice(reflect.SliceOf(t), packets, packets) 
    for i := 0; i < packets; i++ { 
     s := reflect.MakeSlice(t, n, n) 
     start := i * n 
     for j := 0; j < n; j++ { 
      s.Index(j).Set(v.Index(j+start)) 
     } 

     p.Index(i).Set(s) 
    } 

    return p.Interface() 
} 

あなたが期待する型に結果をキャストする必要があります。例:

res := genToPackages([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 5).([][]int) 
関連する問題