1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| func TestPartitionBy(t *testing.T) { type args struct { vs interface{} size int } tests := []struct { name string args args want interface{} }{ {"empty slice", args{[]int{}, 1}, [][]int{}}, {"by 1", args{[]int{1, 2, 3}, 1}, [][]int{{1}, {2}, {3}}}, {"by 2", args{[]int{1, 2, 3}, 2}, [][]int{{1, 2}, {3}}}, {"by 3", args{[]int{1, 2, 3}, 3}, [][]int{{1, 2, 3}}}, {"by 4", args{[]int{1, 2, 3}, 4}, [][]int{{1, 2, 3}}}, {"by 5", args{[]int{1, 2, 3}, 5}, [][]int{{1, 2, 3}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := PartitionBy(tt.args.vs, tt.args.size); !reflect.DeepEqual(got, tt.want) { t.Errorf("PartitionBy() = %v, want %v", got, tt.want) } }) } }
func PartitionBy(vs interface{}, size int) interface{} { if size < 1 { panic("illegal size") } t := reflect.TypeOf(vs) if t.Kind() != reflect.Slice { panic("typ should be slice") }
v := reflect.ValueOf(vs) vlen := v.Len() length := (vlen + size - 1) / size
resultValue := reflect.MakeSlice(reflect.SliceOf(t), length, length)
for i := 0; i < length; i++ { begin := i * size end := begin + size if end > vlen { end = vlen } resultValue.Index(i).Set(v.Slice(begin, end)) }
return resultValue.Interface() }
|