diff --git a/slice/slice.go b/slice/slice.go index dca073c..bf23c5d 100644 --- a/slice/slice.go +++ b/slice/slice.go @@ -421,6 +421,23 @@ func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U { return result } +// FilterMap returns a slice which apply both filtering and mapping to the given slice. +// iteratee callback function should returntwo values: +// 1, mapping result. +// 2, whether the result element should be included or not +// Play: todo +func FilterMap[T any, U any](slice []T, iteratee func(index int, item T) (U, bool)) []U { + result := []U{} + + for i, v := range slice { + if a, ok := iteratee(i, v); ok { + result = append(result, a) + } + } + + return result +} + // Reduce creates an slice of values by running each element of slice thru iteratee function. // Play: https://go.dev/play/p/_RfXJJWIsIm func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T { diff --git a/slice/slice_example_test.go b/slice/slice_example_test.go index dc663c0..3f4807f 100644 --- a/slice/slice_example_test.go +++ b/slice/slice_example_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math" "reflect" + "strconv" ) func ExampleContain() { @@ -367,6 +368,24 @@ func ExampleMap() { // [2 3 4] } +func ExampleFilterMap() { + nums := []int{1, 2, 3, 4, 5} + + getEvenNumStr := func(i, num int) (string, bool) { + if num%2 == 0 { + return strconv.FormatInt(int64(num), 10), true + } + return "", false + } + + result := FilterMap(nums, getEvenNumStr) + + fmt.Printf("%#v", result) + + // Output: + // []string{"2", "4"} +} + func ExampleReduce() { nums := []int{1, 2, 3} diff --git a/slice/slice_test.go b/slice/slice_test.go index 1c28f87..563a582 100644 --- a/slice/slice_test.go +++ b/slice/slice_test.go @@ -3,6 +3,7 @@ package slice import ( "fmt" "math" + "strconv" "testing" "github.com/duke-git/lancet/v2/internal" @@ -315,6 +316,23 @@ func TestMap(t *testing.T) { assert.Equal(studentsOfAdd10Aage, Map(students, mapFunc)) } +func TestFilterMap(t *testing.T) { + assert := internal.NewAssert(t, "TestFilterMap") + + nums := []int{1, 2, 3, 4, 5} + + getEvenNumStr := func(i, num int) (string, bool) { + if num%2 == 0 { + return strconv.FormatInt(int64(num), 10), true + } + return "", false + } + + result := FilterMap(nums, getEvenNumStr) + + assert.Equal([]string{"2", "4"}, result) +} + func TestReduce(t *testing.T) { cases := [][]int{ {},