在写代码过程中,有时候需要做一些批量 查询/操作,往往会涉及将一个很大的数组或切片进行分块。
比如我们有一个存着id的数组,要根据id请求某个接口查询信息,这个接口支持批量查询,但是每次查询的数量上限是100。最好的做法是每次从数组中取最多100个id,进行批量查询,直到遍历完数组。
这个操作不复杂,可以简单的用循环实现,但是每次遇到这种场景都需要写一次代码,有点写吐了。所以就想写一个函数,可以将[]T
按需求拆分成[][]T
。
但是go的泛型还没有来,所以只能用反射来搞了。
献祭我的周六饭后时光
传入[]T
,T
可以是任意类型,按指定大小分块,返回[][]T
。
例子中将[0,1,2,3,4,5,6,7,8,9]
划分成了[0,1,2]
、[3,4,5]
、[6,7,8]
、[9]
https://github.com/kirito41dd/xslice
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package main
import (
"fmt"
"github.com/kirito41dd/xslice"
)
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
i := xslice.SplitToChunks(s, 3)
ss := i.([][]int)
fmt.Println(ss) // [[0 1 2] [3 4 5] [6 7 8] [9]]
}
|
反射一把梭,自然离不了可爱的interface{}
欢迎复制或引包github.com/kirito41dd/xslice
使用,如果以后搬砖遇到其他场景,也会继续扩充。
还是期待go泛型早点到来(那时候我rust应该已经很6了吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
func SplitToChunks(slice interface{}, chunkSize int) interface{} {
sliceType := reflect.TypeOf(slice)
sliceVal := reflect.ValueOf(slice)
length := sliceVal.Len()
if sliceType.Kind() != reflect.Slice {
panic("parameter must be []T")
}
n := 0
if length%chunkSize > 0 {
n = 1
}
SST := reflect.MakeSlice(reflect.SliceOf(sliceType), 0, length/chunkSize+n)
st, ed := 0, 0
for st < length {
ed = st + chunkSize
if ed > length {
ed = length
}
SST = reflect.Append(SST, sliceVal.Slice(st, ed))
st = ed
}
return SST.Interface()
}
|