2016-02-03 8 views
6

私はそれに210万文字のログ文字列を持つスライスを持っており、できるだけ均等に分布しているスライスのスライスを作成したいと思います。ここでSlice chunking in Go

は、私がこれまで持っているものです。

// logs is a slice with ~2.1 million strings in it. 
var divided = make([][]string, 0) 
NumCPU := runtime.NumCPU() 
ChunkSize := len(logs)/NumCPU 
for i := 0; i < NumCPU; i++ { 
    temp := make([]string, 0) 
    idx := i * ChunkSize 
    end := i * ChunkSize + ChunkSize 
    for x := range logs[idx:end] { 
     temp = append(temp, logs[x]) 
    } 
    if i == NumCPU { 
     for x := range logs[idx:] { 
      temp = append(temp, logs[x]) 
     } 
    } 
    divided = append(divided, temp) 
} 

idx := i * ChunkSizeが私にlogsインデックスの現在の「チャンク開始」を与えるだろう、とend := i * ChunkSize + ChunkSizeは私に「チャンク終わり」、またはの終わりを与えますそのチャンクの範囲。私は、スライスを分割/分割する方法やGoの限られた範囲で繰り返す方法に関するドキュメンテーションや例を見つけることができませんでした。これは私が思いついたものです。ただし、最初のチャンクは複数回しかコピーされないため、動作しません。

Goでスライスを(できるだけ均等に)チャンクしますか?

答えて

17

新しいスライスを作成する必要はありません。スライスにlogsのスライスを追加するだけです。それは、私が行方不明になったものだAhhhhhhh

http://play.golang.org/p/vyihJZlDVy

var divided [][]string 

chunkSize := (len(logs) + numCPU - 1)/numCPU 

for i := 0; i < len(logs); i += chunkSize { 
    end := i + chunkSize 

    if end > len(logs) { 
     end = len(logs) 
    } 

    divided = append(divided, logs[i:end]) 
} 

fmt.Printf("%#v\n", divided) 
+0

。私は塊の長さで反復するのではなく、限られた範囲で反復しようとし続けました。私は8時間を使って私の仕事をどうやって実現するかを考えました。答えてくれてありがとう、超便利。 – mxplusb

+0

あなたは「分割された」長さで1つ離れているように見えます。たとえば、 'numCPU = 3; logs = logs [:8]; chunkSize:= len(ログ)/ numCPU;もしchunkSize == 0 {chunkSize = 1};は3つのcpusと8つのログに対して3ではなく4に分割する:http://play.golang.org/p/EdhiclVR0q。 'chunkSize'については、' chunkSize:=(len(logs)+ numCPU - 1)/ numCPU; ':http://play.golang.org/p/xDyFXt45Fzと書いてください。 – peterSO

+0

@peterSO:ありがとう、ちょうど元からコピーして、チェックするとは思わなかった。 – JimB