Must efficient way to cut slice

polaris · · 506 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hi , I have an issue with the Datastore when im trying to do batch operations. I want to protect the 500 entities per batch limit.</p> <p>What is the best way to split the slice to 500 entities per slice ? let </p> <p><a href="https://github.com/golang/go/wiki/SliceTricks">SliceTricks</a> Maybe curing the slice to a new one like that ? a = append(a[:i], a[j:]...)</p> <p>Im basically want to tack a slice of size N and split it to 500 each</p> <hr/>**评论:**<br/><br/>ergotayours: <pre><p>Can you be more specific? I&#39;m not sure I understand what you&#39;re trying to accomplish.</p> <p>Are you trying to split the slice into sections of 500 each? If so, you could do something like</p> <pre><code>for i := 0; i &lt; len(a); i += 500 { batch := a[i:min(i+500, len(a))] // Do something with batch } </code></pre> <p>where <code>min</code> would be something like</p> <pre><code>func min(a, b int) int { if a &lt;= b { return a } return b } </code></pre> <p>The last <code>batch</code> might contain less than 500 elements, which sounds like it&#39;s okay given your description.</p> <p>EDIT: As <a href="/u/miko5054">/u/miko5054</a> points out, the upper slice bound is exclusive, so it should be <code>min(i+500, len(a))</code>. Sorry for the error; I haven&#39;t done slice stuff in a while!</p></pre>miko5054: <pre><blockquote> <p>func min(a, b int) int { if a &lt;= b { return a } return b }</p> </blockquote> <p>i think this is the correct way ?</p> <pre><code> a := []int{1, 2, 3, 4, 5, 6, 7, 8} for i := 0; i &lt; len(a); i += 2 { batch := a[i:min(i+2, len(a))] &lt;---- fmt.Println(batch) } </code></pre></pre>SteveMcQwark: <pre><p>Yes, you want to slice to <code>len(a)</code> because it&#39;s an exclusive bound, and you want to include the last element at <code>len(a)-1</code>. <code>i + stride</code> should already give you the element <em>after</em> the batch, so that&#39;s fine.</p></pre>mc_hammerd: <pre><p>slicetricks says <code>b = append(a[:500], a[500:]...)</code></p> <p>my guess would be skipping the append is faster</p> <p>(slices are just pointers to arrays so this should be fast).</p> <pre><code>lena := len(a) lenb := lena/500+1 b := make([][]int,lenb) // for example ill use int for i,_ := range b { start := i*500 end := start+500 if end &gt; lena { end=lena } b[i] = a[start:end] } for i,v := range b { fmt.Println(i,&#34;:&#34;,v) } //print </code></pre></pre>barsonme: <pre><p>I&#39;d benchmark it. I have a feeling append won&#39;t be the fastest, but don&#39;t listen to me -- benchmark.</p> <p>The non-append way would be to allocate len(slice)/500 and then copy over in chunks. </p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

506 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传