Commit 0610463

mo khan <mo@mokhan.ca>
2022-10-23 04:01:12
feat: add each and inject
1 parent 841f107
Changed files (2)
pkg/x/iterate.go
@@ -1,7 +1,8 @@
 package x
 
-type Predicate[T any] func(T) bool
 type Mapper[T any, K any] func(T) K
+type Predicate[T any] func(T) bool
+type Visitor[T any] func(T)
 
 func Find[T any](items []T, predicate Predicate[T]) T {
 	for _, item := range items {
@@ -14,23 +15,35 @@ func Find[T any](items []T, predicate Predicate[T]) T {
 
 func FindAll[T any](items []T, predicate Predicate[T]) []T {
 	results := []T{}
-	for _, item := range items {
+	Each[T](items, func(item T) {
 		if predicate(item) {
 			results = append(results, item)
 		}
-	}
+	})
 	return results
 }
 
 func Contains[T comparable](items []T, predicate Predicate[T]) bool {
-	item := Find[T](items, predicate)
-	return item != Default[T]()
+	return Find[T](items, predicate) != Default[T]()
 }
 
 func Map[TInput any, TOutput any](items []TInput, mapFrom Mapper[TInput, TOutput]) []TOutput {
 	results := []TOutput{}
-	for _, item := range items {
+	Each[TInput](items, func(item TInput) {
 		results = append(results, mapFrom(item))
-	}
+	})
 	return results
 }
+
+func Each[T any](items []T, v Visitor[T]) {
+	for _, item := range items {
+		v(item)
+	}
+}
+
+func Inject[TInput any, TOutput any](items []TInput, memo TOutput, f func(TOutput, TInput)) TOutput {
+	for _, item := range items {
+		f(memo, item)
+	}
+	return memo
+}
pkg/x/iterate_test.go
@@ -5,6 +5,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestFind(t *testing.T) {
@@ -82,3 +83,32 @@ func TestMap(t *testing.T) {
 		assert.Equal(t, []string{"1", "2", "3"}, result)
 	})
 }
+
+func TestEach(t *testing.T) {
+	t.Run("visits each item", func(t *testing.T) {
+		results := []int{}
+
+		Each([]int{1, 2, 3}, func(i int) {
+			results = append(results, i)
+		})
+
+		assert.Equal(t, []int{1, 2, 3}, results)
+	})
+}
+
+func TestInject(t *testing.T) {
+	t.Run("collects each item", func(t *testing.T) {
+		items := []int{1, 3, 6}
+
+		result := Inject[int, map[int]bool](items,
+			map[int]bool{},
+			func(memo map[int]bool, item int) {
+				memo[item] = true
+			})
+
+		require.NotNil(t, result)
+		assert.True(t, result[1])
+		assert.True(t, result[3])
+		assert.True(t, result[6])
+	})
+}