From 73ed4021a60ac6492b00b69a3c8460c2da08f6a1 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Sun, 2 Jan 2022 18:51:18 -0400 Subject: [PATCH] feat: chain package --- README.md | 4 ++-- chain.go => chain/chain.go | 34 ++++++++++++++++------------ chain_test.go => chain/chain_test.go | 26 ++++++++++----------- 3 files changed, 34 insertions(+), 30 deletions(-) rename chain.go => chain/chain.go (80%) rename chain_test.go => chain/chain_test.go (82%) diff --git a/README.md b/README.md index d763372..67085e4 100644 --- a/README.md +++ b/README.md @@ -102,10 +102,10 @@ go test ./... ### Chaining -Calling `NewChain` will cause all future method calls to return wrapped objects. When you've finished the computation, +Calling `chain.Of` will cause all future method calls to return wrapped values. When you've finished the computation, call `Value` to retrieve the final value. -Methods not returning a slice such as `Reduce`, `Every`, `Some`, will break the chain and return `Value` instantly. +Methods not returning a slice such as `Reduce`, `Every`, `Some`, will break the `Chain` and return `Value` instantly. ## Built With diff --git a/chain.go b/chain/chain.go similarity index 80% rename from chain.go rename to chain/chain.go index ba68dd6..5e392cd 100644 --- a/chain.go +++ b/chain/chain.go @@ -1,40 +1,44 @@ -package underscore +package chain -import "constraints" +import ( + "constraints" + + u "github.com/rjNemo/underscore" +) type Chain[T constraints.Ordered] struct { Value []T } -// NewChain starts a Chain. All future method calls will return Chain structs. When you've finished the computation, +// Of starts a Chain. All future method calls will return Chain structs. When you've finished the computation, // call Value to retrieve the final value. // // Methods not returning a slice such as Reduce, Every, Some, will break the chain and return Value instantly. -func NewChain[T constraints.Ordered](value []T) Chain[T] { +func Of[T constraints.Ordered](value []T) Chain[T] { return Chain[T]{Value: value} } // Contains returns true if the value is present in the slice and breaks the Chain. func (c Chain[T]) Contains(value T) bool { - return Contains(c.Value, value) + return u.Contains(c.Value, value) } // Each iterates over a slice of elements, yielding each in turn to an action function. // Breaks the Chain. func (c Chain[T]) Each(action func(T)) { - Each(c.Value, action) + u.Each(c.Value, action) } // Every returns true if all the values in the slice pass the predicate truth test. // Short-circuits and stops traversing the slice if a false element is found. // Breaks the Chain. func (c Chain[T]) Every(predicate func(T) bool) bool { - return Every(c.Value, predicate) + return u.Every(c.Value, predicate) } // Filter looks through each value in the slice, returning a slice of all the values that pass a truth test (predicate). func (c Chain[T]) Filter(predicate func(n T) bool) Chain[T] { - return Chain[T]{Value: Filter(c.Value, predicate)} + return Chain[T]{Value: u.Filter(c.Value, predicate)} } // Find looks through each value in the slice, returning the first one that passes a truth test (predicate), @@ -42,7 +46,7 @@ func (c Chain[T]) Filter(predicate func(n T) bool) Chain[T] { // The function returns as soon as it finds an acceptable element, and doesn't traverse the entire slice. // Breaks the Chain. func (c Chain[T]) Find(predicate func(n T) bool) (T, error) { - return Find(c.Value, predicate) + return u.Find(c.Value, predicate) } // Map produces a new slice of values by mapping each value in the slice through @@ -50,7 +54,7 @@ func (c Chain[T]) Find(predicate func(n T) bool) (T, error) { // // TODO: Move from T to P. func (c Chain[T]) Map(transform func(n T) T) Chain[T] { - return Chain[T]{Value: Map(c.Value, transform)} + return Chain[T]{Value: u.Map(c.Value, transform)} } // Max returns the maximum value in the slice. @@ -58,7 +62,7 @@ func (c Chain[T]) Map(transform func(n T) T) Chain[T] { // This function uses operator <. // Breaks the Chain. func (c Chain[T]) Max() T { - return Max(c.Value) + return u.Max(c.Value) } // Min returns the minimum value in the slice. @@ -66,25 +70,25 @@ func (c Chain[T]) Max() T { // This function uses operator <. // Breaks the Chain. func (c Chain[T]) Min() T { - return Min(c.Value) + return u.Min(c.Value) } // Partition splits the slice into two slices: one whose elements all satisfy predicate // and one whose elements all do not satisfy predicate. // Breaks the Chain. func (c Chain[T]) Partition(predicate func(T) bool) ([]T, []T) { - return Partition(c.Value, predicate) + return u.Partition(c.Value, predicate) } // Reduce combine a list of values into a single value and breaks the Chain. // acc is the initial state, and each successive step of it should be returned by the reduction function. func (c Chain[T]) Reduce(reducer func(n, acc T) T, acc T) T { - return Reduce(c.Value, reducer, acc) + return u.Reduce(c.Value, reducer, acc) } // Some returns true if any of the values in the slice pass the predicate truth test. // Short-circuits and stops traversing the slice if a true element is found. // Breaks the Chain. func (c Chain[T]) Some(predicate func(T) bool) bool { - return Some(c.Value, predicate) + return u.Some(c.Value, predicate) } diff --git a/chain_test.go b/chain/chain_test.go similarity index 82% rename from chain_test.go rename to chain/chain_test.go index b669314..53458dc 100644 --- a/chain_test.go +++ b/chain/chain_test.go @@ -1,18 +1,18 @@ -package underscore_test +package chain_test import ( "testing" "github.com/stretchr/testify/assert" - u "github.com/rjNemo/underscore" + "github.com/rjNemo/underscore/chain" ) func TestChainFilter(t *testing.T) { want := []int{2, 4, 6, 8} assert.Equal(t, want, - u.NewChain(nums).Filter(isEven).Value, + chain.Of(nums).Filter(isEven).Value, ) } @@ -20,7 +20,7 @@ func TestChainFilterMap(t *testing.T) { want := []int{4, 16, 36, 64} assert.Equal(t, want, - u.NewChain(nums). + chain.Of(nums). Filter(isEven). Map(toSquare). Value) @@ -30,14 +30,14 @@ func TestChainFilterMapReduce(t *testing.T) { want := 120 assert.Equal(t, want, - u.NewChain(nums). + chain.Of(nums). Filter(isEven). Map(toSquare). Reduce(sum, 0)) } func TestChainFilterMapContains(t *testing.T) { - assert.True(t, u.NewChain(nums). + assert.True(t, chain.Of(nums). Filter(isEven). Map(toSquare). Contains(16)) @@ -46,7 +46,7 @@ func TestChainFilterMapContains(t *testing.T) { func TestChainFilterMapEach(t *testing.T) { want := []int{5, 17, 37, 65} res := make([]int, 0) - u.NewChain(nums). + chain.Of(nums). Filter(isEven). Map(toSquare). Each(func(n int) { res = append(res, n+1) }) @@ -54,14 +54,14 @@ func TestChainFilterMapEach(t *testing.T) { } func TestChainFilterMapEvery(t *testing.T) { - assert.True(t, u.NewChain(nums). + assert.True(t, chain.Of(nums). Filter(isEven). Map(toSquare). Every(func(n int) bool { return n%4 == 0 })) } func TestChainFilterMapFind(t *testing.T) { - n, err := u.NewChain(nums). + n, err := chain.Of(nums). Filter(isEven). Map(toSquare). Find(func(n int) bool { return n%4 == 0 }) @@ -71,7 +71,7 @@ func TestChainFilterMapFind(t *testing.T) { func TestChainFilterMapMax(t *testing.T) { want := 64 - assert.Equal(t, want, u.NewChain(nums). + assert.Equal(t, want, chain.Of(nums). Filter(isEven). Map(toSquare). Max()) @@ -79,7 +79,7 @@ func TestChainFilterMapMax(t *testing.T) { func TestChainFilterMapMin(t *testing.T) { w := 4 - assert.Equal(t, w, u.NewChain(nums). + assert.Equal(t, w, chain.Of(nums). Filter(isEven). Map(toSquare). Min()) @@ -88,7 +88,7 @@ func TestChainFilterMapMin(t *testing.T) { func TestChainFilterMapPartition(t *testing.T) { wantLeft := []int{4, 16} wantRight := []int{36, 64} - left, right := u.NewChain(nums). + left, right := chain.Of(nums). Filter(isEven). Map(toSquare). Partition(func(n int) bool { return n < 20 }) @@ -98,7 +98,7 @@ func TestChainFilterMapPartition(t *testing.T) { } func TestChainFilterMapSome(t *testing.T) { - assert.True(t, u.NewChain(nums). + assert.True(t, chain.Of(nums). Filter(isEven). Map(toSquare). Some(func(n int) bool { return n%64 == 0 }))