diff --git a/each.go b/each.go index 809098c..ea04159 100644 --- a/each.go +++ b/each.go @@ -1,8 +1,10 @@ package underscore // Each iterates over a slice of elements, yielding each in turn to an action function. -func Each[T any](values []T, action func(T)) { +// Returns the slice for chaining. +func Each[T any](values []T, action func(T)) []T { for _, v := range values { action(v) } + return values } diff --git a/each_test.go b/each_test.go index 1f4da32..9082869 100644 --- a/each_test.go +++ b/each_test.go @@ -20,3 +20,14 @@ func TestEach(t *testing.T) { assert.Equal(t, want, res) } + +func TestEachReturnsInitialSlice(t *testing.T) { + names := []string{"Alice", "Bob", "Charles"} + want := []string{"Alice", "Bob", "Charles"} + + res := make([]string, 0) + + assert.Equal(t, want, underscore.Each(names, func(n string) { + res = append(res, fmt.Sprintf("Hi %s", n)) + })) +} diff --git a/examples/chaining.go b/examples/chaining.go index f4b5a9d..2e863f3 100644 --- a/examples/chaining.go +++ b/examples/chaining.go @@ -10,6 +10,6 @@ func chaining() int { Filter(func(n int) bool { return n%2 == 0 }). // square every number in the slice Map(func(n int) int { return n * n }). - // reduce to the sum + // reduce the slice to its sum Reduce(func(n, acc int) int { return n + acc }, 0) } diff --git a/examples/filterMapReduce.go b/examples/filterMapReduce.go index f295eb4..74752f8 100644 --- a/examples/filterMapReduce.go +++ b/examples/filterMapReduce.go @@ -10,7 +10,7 @@ func filterMapReduce() int { evens := u.Filter(numbers, func(n int) bool { return n%2 == 0 }) // square every number in the slice squares := u.Map(evens, func(n int) int { return n * n }) - // reduce to the sum + // reduce the slice to its sum res := u.Reduce(squares, func(n, acc int) int { return n + acc }, 0) return res diff --git a/maps/map.go b/maps/map.go new file mode 100644 index 0000000..ac3a404 --- /dev/null +++ b/maps/map.go @@ -0,0 +1,16 @@ +package maps + +type M[K comparable, V any] map[K]V + +// Map produces a new slice of values by mapping each value in the slice through +// a transform function. +func Map[K, Q comparable, V, W any](m M[K, V], f func(K, V) M[Q, W]) M[Q, W] { + res := make(M[Q, W], len(m)) + for k, v := range m { + mm := f(k, v) + for k2, v2 := range mm { + res[k2] = v2 + } + } + return res +} diff --git a/maps/map_test.go b/maps/map_test.go new file mode 100644 index 0000000..ee6e249 --- /dev/null +++ b/maps/map_test.go @@ -0,0 +1,40 @@ +package maps_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + u "github.com/rjNemo/underscore" + m "github.com/rjNemo/underscore/maps" +) + +func TestMap(t *testing.T) { + scores := m.M[string, int]{ + "alice": 0, + "bob": 10, + "clara": 7, + "david": 23, + } + + hasWon := func(key string, value int) m.M[string, bool] { return m.M[string, bool]{key: value > 21} } + want := m.M[string, bool]{ + "alice": false, + "bob": false, + "clara": false, + "david": true} + assert.Equal(t, want, m.Map(scores, hasWon)) +} + +func TestMapSlices(t *testing.T) { + scores := []m.M[string, int]{ + {"score": 0}, + {"score": 10}, + {"score": 7}, + {"score": 23}, + } + + hasWon := func(s m.M[string, int]) bool { return s["score"] > 21 } + want := []bool{false, false, false, true} + assert.Equal(t, want, u.Map(scores, hasWon)) +}