From 6a1a0b8677e132fc53a828d715256833533fbf48 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Sat, 22 Jan 2022 21:16:34 +0800 Subject: [PATCH] feat: add Concat func --- slice/slice.go | 59 +++++++++++++++++++++++++++++++++++++++------ slice/slice_test.go | 53 ++++++++++++++++++++-------------------- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/slice/slice.go b/slice/slice.go index ea9e1f8..0e978a6 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -102,21 +102,64 @@ func Chunk(slice []interface{}, size int) [][]interface{} { return res } -// Difference creates an slice of whose element not included in the other given slice -func Difference(slice1, slice2 interface{}) interface{} { - v := sliceValue(slice1) +// Compact creates an slice with all falsey values removed. The values false, nil, 0, and "" are falsey +func Compact(slice interface{}) interface{} { + sv := sliceValue(slice) var indexes []int - for i := 0; i < v.Len(); i++ { - vi := v.Index(i).Interface() - if !Contain(slice2, vi) { + for i := 0; i < sv.Len(); i++ { + item := sv.Index(i).Interface() + if item != nil && item != false && item != "" && item != 0 { + indexes = append(indexes, i) + } + } + res := reflect.MakeSlice(sv.Type(), len(indexes), len(indexes)) + for i := range indexes { + res.Index(i).Set(sv.Index(indexes[i])) + } + + return res.Interface() +} + +// Concat creates a new slice concatenating slice with any additional slices and/or values. +func Concat(slice interface{}, values ...interface{}) interface{} { + sv := sliceValue(slice) + size := sv.Len() + + res := reflect.MakeSlice(sv.Type(), size, size) + for i := 0; i < size; i++ { + res.Index(i).Set(sv.Index(i)) + } + + for _, v := range values { + if reflect.TypeOf(v).Kind() == reflect.Slice { + vv := reflect.ValueOf(v) + for i := 0; i < vv.Len(); i++ { + res = reflect.Append(res, vv.Index(i)) + } + } else { + res = reflect.Append(res, reflect.ValueOf(v)) + } + } + + return res.Interface() +} + +// Difference creates an slice of whose element in slice1, not in slice2 +func Difference(slice1, slice2 interface{}) interface{} { + sv := sliceValue(slice1) + + var indexes []int + for i := 0; i < sv.Len(); i++ { + item := sv.Index(i).Interface() + if !Contain(slice2, item) { indexes = append(indexes, i) } } - res := reflect.MakeSlice(v.Type(), len(indexes), len(indexes)) + res := reflect.MakeSlice(sv.Type(), len(indexes), len(indexes)) for i := range indexes { - res.Index(i).Set(v.Index(indexes[i])) + res.Index(i).Set(sv.Index(indexes[i])) } return res.Interface() } diff --git a/slice/slice_test.go b/slice/slice_test.go index ea452d8..9bd5b51 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -36,44 +36,43 @@ func TestChunk(t *testing.T) { assert := internal.NewAssert(t, "TestChunk") arr := []string{"a", "b", "c", "d", "e"} - r1 := [][]interface{}{ - {"a"}, - {"b"}, - {"c"}, - {"d"}, - {"e"}, - } + r1 := [][]interface{}{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}} assert.Equal(r1, Chunk(InterfaceSlice(arr), 1)) - r2 := [][]interface{}{ - {"a", "b"}, - {"c", "d"}, - {"e"}, - } + r2 := [][]interface{}{{"a", "b"}, {"c", "d"}, {"e"}} assert.Equal(r2, Chunk(InterfaceSlice(arr), 2)) - r3 := [][]interface{}{ - {"a", "b", "c"}, - {"d", "e"}, - } + r3 := [][]interface{}{{"a", "b", "c"}, {"d", "e"}} assert.Equal(r3, Chunk(InterfaceSlice(arr), 3)) - r4 := [][]interface{}{ - {"a", "b", "c", "d"}, - {"e"}, - } + r4 := [][]interface{}{{"a", "b", "c", "d"}, {"e"}} assert.Equal(r4, Chunk(InterfaceSlice(arr), 4)) - r5 := [][]interface{}{ - {"a"}, - {"b"}, - {"c"}, - {"d"}, - {"e"}, - } + r5 := [][]interface{}{{"a"}, {"b"}, {"c"}, {"d"}, {"e"}} assert.Equal(r5, Chunk(InterfaceSlice(arr), 5)) } +func TestCompact(t *testing.T) { + assert := internal.NewAssert(t, "TesCompact") + + assert.Equal([]int{}, Compact([]int{0})) + assert.Equal([]int{1, 2, 3}, Compact([]int{0, 1, 2, 3})) + assert.Equal([]string{}, Compact([]string{""})) + assert.Equal([]string{""}, Compact([]string{" "})) + assert.Equal([]string{"a", "b", "0"}, Compact([]string{"", "a", "b", "0"})) + assert.Equal([]bool{true, true}, Compact([]bool{false, true, true})) +} + +func TestConcat(t *testing.T) { + assert := internal.NewAssert(t, "Concat") + + assert.Equal([]int{0}, Concat([]int{}, 0)) + assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, 4, 5)) + assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4, 5})) + assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, []int{5})) + assert.Equal([]int{1, 2, 3, 4, 5}, Concat([]int{1, 2, 3}, []int{4}, 5)) +} + func TestEvery(t *testing.T) { nums := []int{1, 2, 3, 5} isEven := func(i, num int) bool {