From 449b5b4dfa932a2e904fa01d0d2ea5ad077b8f7c Mon Sep 17 00:00:00 2001 From: tuannguyen Date: Sun, 6 Aug 2023 18:33:04 +0700 Subject: [PATCH] feat: add the func includes --- collection/includes.go | 36 +++++++++++++++++++ collection/includes_test.go | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 collection/includes.go create mode 100644 collection/includes_test.go diff --git a/collection/includes.go b/collection/includes.go new file mode 100644 index 0000000..9e2200d --- /dev/null +++ b/collection/includes.go @@ -0,0 +1,36 @@ +package collection + +import ( + "reflect" + + "github.com/warriors-vn/go-dash/constants" +) + +// includes checks if the input array contains the specified search value. +// It takes an array-like data structure, a search value, and an optional starting index. +// If the starting index is provided, the search starts from that index. +// The function returns true if the search is found, false otherwise, or an error if any occurs. +func includes(array interface{}, search interface{}, fromIndex ...int) (interface{}, error) { + arrValue, searchValue := reflect.ValueOf(array), reflect.ValueOf(search) + + if arrValue.Kind() != reflect.Slice && arrValue.Kind() != reflect.Array { + return false, constants.ErrNotSlice + } + + from := 0 + if fromIndex != nil && fromIndex[0] > 0 { + from = fromIndex[0] + } + + if from >= arrValue.Len() { + return false, nil + } + + for i := from; i < arrValue.Len(); i++ { + if reflect.DeepEqual(arrValue.Index(i).Interface(), searchValue.Interface()) { + return true, nil + } + } + + return false, nil +} diff --git a/collection/includes_test.go b/collection/includes_test.go new file mode 100644 index 0000000..88e4430 --- /dev/null +++ b/collection/includes_test.go @@ -0,0 +1,71 @@ +package collection + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/warriors-vn/go-dash/constants" +) + +func Test_includes_valid_int(t *testing.T) { + result, err := includes([]int{1, 2, 3, 4, 5}, 3) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_int64(t *testing.T) { + result, err := includes([]int64{1, 2, 3, 4, 5}, int64(5)) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_float64(t *testing.T) { + result, err := includes([]float64{1.1, 2.2, 3.3, 4.4, 5.5}, 5.5, 2) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_string(t *testing.T) { + result, err := includes([]string{"1.1", "2.2", "3.3", "4.4", "5.5"}, "5.5", 3) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_interface(t *testing.T) { + result, err := includes([]interface{}{"1.1", true, 3.3, 4, false}, true) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_not_include(t *testing.T) { + result, err := includes([]interface{}{"1.1", true, 3.3, false}, 3) + + assert.Equal(t, false, result) + assert.Nil(t, err) +} + +func Test_includes_valid_bool(t *testing.T) { + result, err := includes([]bool{true, true, false}, true, 1) + + assert.Equal(t, true, result) + assert.Nil(t, err) +} + +func Test_includes_valid_from_great_than_array_length(t *testing.T) { + result, err := includes([]bool{true, true, false}, true, 10) + + assert.Equal(t, false, result) + assert.Nil(t, err) +} + +func Test_includes_invalid_array_not_slice(t *testing.T) { + result, err := includes(true, true) + + assert.Equal(t, false, result) + assert.Equal(t, constants.ErrNotSlice, err) +}