From 9bb1e4d153b6a18b54ad646577d0fdb4c6a3c085 Mon Sep 17 00:00:00 2001 From: andeya Date: Thu, 8 Sep 2022 00:20:41 +0800 Subject: [PATCH] chore(iter): update Flatten --- examples/iterator/flatten_test.go | 17 ++++ examples/overview_test.go | 2 +- iter/export.go | 8 +- iter/iter_flatten.go | 136 +++++++++++++++--------------- 4 files changed, 90 insertions(+), 73 deletions(-) create mode 100644 examples/iterator/flatten_test.go diff --git a/examples/iterator/flatten_test.go b/examples/iterator/flatten_test.go new file mode 100644 index 0000000..577b346 --- /dev/null +++ b/examples/iterator/flatten_test.go @@ -0,0 +1,17 @@ +package iterator_test + +import ( + "testing" + + "github.com/andeya/gust/iter" + "github.com/stretchr/testify/assert" +) + +func TestFlatten(t *testing.T) { + var i = iter.FromElements( + iter.FromElements([]int{1, 2}, []int{3, 4}), + iter.FromElements([]int{5, 6}, []int{7, 8}), + ) + var d2 = iter.DeFlatten[iter.DeIterator[[]int], []int](i).Collect() + assert.Equal(t, [][]int{{1, 2}, {3, 4}, {5, 6}, {7, 8}}, d2) +} diff --git a/examples/overview_test.go b/examples/overview_test.go index 3aec03c..a83a760 100644 --- a/examples/overview_test.go +++ b/examples/overview_test.go @@ -57,7 +57,7 @@ func TestResultFlatten(t *testing.T) { var results []gust.Result[uint64] var errs []error var nums = iter. - Flatten[uint64, gust.Result[uint64]]( + Flatten[gust.Result[uint64], uint64]( iter.Map[string, gust.Result[uint64]]( iter.FromElements("17", "not a number", "99", "-27", "768"), func(s string) gust.Result[uint64] { return gust.Ret(strconv.ParseUint(s, 10, 64)) }, diff --git a/iter/export.go b/iter/export.go index d5323c4..daa388f 100644 --- a/iter/export.go +++ b/iter/export.go @@ -406,13 +406,13 @@ func Scan[T any, St any, B any](iter Iterator[T], initialState St, f func(state } // Flatten creates an iterator that flattens nested structure. -func Flatten[T any, D gust.Iterable[T]](iter Iterator[D]) Iterator[T] { - return newFlattenIterator[T, D](iter) +func Flatten[I gust.Iterable[T], T any](iter Iterator[I]) Iterator[T] { + return newFlattenIterator[I, T](iter) } // DeFlatten creates a double ended iterator that flattens nested structure. -func DeFlatten[T any, D gust.DeIterable[T]](iter DeIterator[D]) DeIterator[T] { - return newDeFlattenIterator[T, D](iter) +func DeFlatten[I gust.DeIterable[T], T any](iter DeIterator[I]) DeIterator[T] { + return newDeFlattenIterator[I, T](iter) } // FlatMap creates an iterator that works like map, but flattens nested structure. diff --git a/iter/iter_flatten.go b/iter/iter_flatten.go index 0464d01..9e8dfc4 100644 --- a/iter/iter_flatten.go +++ b/iter/iter_flatten.go @@ -5,49 +5,49 @@ import ( "github.com/andeya/gust/opt" ) -func newFlattenIterator[T any, D gust.Iterable[T]](iter Iterator[D]) Iterator[T] { - p := &flattenIterator[T, D]{iter: iter.Fuse()} +func newFlattenIterator[I gust.Iterable[T], T any](iter Iterator[I]) Iterator[T] { + p := &flattenIterator[I, T]{iter: iter.Fuse()} p.setFacade(p) return p } -func newDeFlattenIterator[T any, D gust.DeIterable[T]](iter DeIterator[D]) DeIterator[T] { - p := &deFlattenIterator[T, D]{iter: iter.DeFuse()} +func newDeFlattenIterator[I gust.DeIterable[T], T any](iter DeIterator[I]) DeIterator[T] { + p := &deFlattenIterator[I, T]{iter: iter.DeFuse()} p.setFacade(p) return p } func newFlatMapIterator[T any, B any](iter Iterator[T], f func(T) Iterator[B]) Iterator[B] { var m = newMapIterator[T, Iterator[B]](iter, f) - return newFlattenIterator[B, Iterator[B]](m) + return newFlattenIterator[Iterator[B], B](m) } func newDeFlatMapIterator[T any, B any](iter DeIterator[T], f func(T) DeIterator[B]) DeIterator[B] { var m = newDeMapIterator[T, DeIterator[B]](iter, f) - return newDeFlattenIterator[B, DeIterator[B]](m) + return newDeFlattenIterator[DeIterator[B], B](m) } var ( - _ Iterator[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealNext[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealSizeHint = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealTryFold[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealFold[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealAdvanceBy[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealCount = (*flattenIterator[any, gust.Iterable[any]])(nil) - _ iRealLast[any] = (*flattenIterator[any, gust.Iterable[any]])(nil) + _ Iterator[any] = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealNext[any] = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealSizeHint = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealTryFold[any] = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealFold[any] = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealAdvanceBy[any] = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealCount = (*flattenIterator[gust.Iterable[any], any])(nil) + _ iRealLast[any] = (*flattenIterator[gust.Iterable[any], any])(nil) ) // flattenIterator is an iterator that flattens one level of nesting in an iterator of things // that can be turned into iterators. -type flattenIterator[T any, D gust.Iterable[T]] struct { +type flattenIterator[I gust.Iterable[T], T any] struct { iterBackground[T] - iter Iterator[D] + iter Iterator[I] frontiter gust.Option[Iterator[T]] backiter gust.Option[Iterator[T]] } -func (f *flattenIterator[T, D]) realNext() gust.Option[T] { +func (f *flattenIterator[I, T]) realNext() gust.Option[T] { for { if f.frontiter.IsSome() { x := f.frontiter.Unwrap().Next().InspectNone(func() { @@ -57,7 +57,7 @@ func (f *flattenIterator[T, D]) realNext() gust.Option[T] { return x } } else { - x := f.iter.Next().Inspect(func(t D) { + x := f.iter.Next().Inspect(func(t I) { f.frontiter = gust.Some(FromIterable[T](t)) }) if x.IsNone() { @@ -72,7 +72,7 @@ func (f *flattenIterator[T, D]) realNext() gust.Option[T] { } } -func (f *flattenIterator[T, D]) realSizeHint() (uint, gust.Option[uint]) { +func (f *flattenIterator[I, T]) realSizeHint() (uint, gust.Option[uint]) { var fl = opt.MapOr(f.frontiter, gust.Pair[uint, gust.Option[uint]]{0, gust.Some[uint](0)}, func(i Iterator[T]) (x gust.Pair[uint, gust.Option[uint]]) { x.A, x.B = i.SizeHint() return x @@ -90,21 +90,21 @@ func (f *flattenIterator[T, D]) realSizeHint() (uint, gust.Option[uint]) { return lo, gust.None[uint]() } -func (f *flattenIterator[T, D]) realTryFold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { +func (f *flattenIterator[I, T]) realTryFold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { return f.iterTryFold(init, func(acc any, item Iterator[T]) gust.AnyCtrlFlow { return item.TryFold(acc, fold) }) } -func (f *flattenIterator[T, D]) realFold(init any, fold func(any, T) any) any { +func (f *flattenIterator[I, T]) realFold(init any, fold func(any, T) any) any { return f.iterFold(init, func(acc any, item Iterator[T]) any { return item.Fold(acc, fold) }) } -func (f *flattenIterator[T, D]) iterTryFold(acc any, fold func(any, Iterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { - var flatten = func(frontiter *gust.Option[Iterator[T]], fold func(any, Iterator[T]) gust.AnyCtrlFlow) func(any, D) gust.AnyCtrlFlow { - return func(acc any, iter D) gust.AnyCtrlFlow { +func (f *flattenIterator[I, T]) iterTryFold(acc any, fold func(any, Iterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { + var flatten = func(frontiter *gust.Option[Iterator[T]], fold func(any, Iterator[T]) gust.AnyCtrlFlow) func(any, I) gust.AnyCtrlFlow { + return func(acc any, iter I) gust.AnyCtrlFlow { return fold(acc, *frontiter.Insert(FromIterable[T](iter))) } } @@ -131,11 +131,11 @@ func (f *flattenIterator[T, D]) iterTryFold(acc any, fold func(any, Iterator[T]) return gust.AnyContinue(acc) } -func (f *flattenIterator[T, D]) iterFold(acc any, fold func(any, Iterator[T]) any) any { +func (f *flattenIterator[I, T]) iterFold(acc any, fold func(any, Iterator[T]) any) any { f.frontiter.Inspect(func(i Iterator[T]) { acc = fold(acc, i) }) - acc = f.iter.Fold(acc, func(acc any, i D) any { + acc = f.iter.Fold(acc, func(acc any, i I) any { return fold(acc, FromIterable[T](i)) }) f.backiter.Inspect(func(i Iterator[T]) { @@ -144,7 +144,7 @@ func (f *flattenIterator[T, D]) iterFold(acc any, fold func(any, Iterator[T]) an return acc } -func (f *flattenIterator[T, D]) realAdvanceBy(n uint) gust.Errable[uint] { +func (f *flattenIterator[I, T]) realAdvanceBy(n uint) gust.Errable[uint] { var advance = func(n any, iter Iterator[T]) gust.AnyCtrlFlow { x := iter.AdvanceBy(n.(uint)) if x.IsErr() { @@ -162,14 +162,14 @@ func (f *flattenIterator[T, D]) realAdvanceBy(n uint) gust.Errable[uint] { return gust.NonErrable[uint]() } -func (f *flattenIterator[T, D]) realCount() uint { +func (f *flattenIterator[I, T]) realCount() uint { var count = func(acc any, iter Iterator[T]) any { return acc.(uint) + iter.Count() } return f.iterFold(uint(0), count).(uint) } -func (f *flattenIterator[T, D]) realLast() gust.Option[T] { +func (f *flattenIterator[I, T]) realLast() gust.Option[T] { var last = func(last any, iter Iterator[T]) any { return iter.Last().Or(last.(gust.Option[T])) } @@ -177,33 +177,33 @@ func (f *flattenIterator[T, D]) realLast() gust.Option[T] { } var ( - _ DeIterator[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealNext[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealNextBack[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealSizeHint = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealTryFold[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealTryRfold[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealFold[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealRfold[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealAdvanceBy[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealAdvanceBackBy[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealCount = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealLast[any] = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) - _ iRealRemaining = (*deFlattenIterator[any, gust.DeIterable[any]])(nil) + _ DeIterator[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealNext[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealNextBack[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealSizeHint = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealTryFold[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealTryRfold[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealFold[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealRfold[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealAdvanceBy[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealAdvanceBackBy[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealCount = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealLast[any] = (*deFlattenIterator[gust.DeIterable[any], any])(nil) + _ iRealRemaining = (*deFlattenIterator[gust.DeIterable[any], any])(nil) ) -type deFlattenIterator[T any, D gust.DeIterable[T]] struct { +type deFlattenIterator[I gust.DeIterable[T], T any] struct { deIterBackground[T] - iter DeIterator[D] + iter DeIterator[I] frontiter gust.Option[DeIterator[T]] backiter gust.Option[DeIterator[T]] } -func (f *deFlattenIterator[T, D]) realRemaining() uint { +func (f *deFlattenIterator[I, T]) realRemaining() uint { return f.iter.Remaining() } -func (f *deFlattenIterator[T, D]) realNextBack() gust.Option[T] { +func (f *deFlattenIterator[I, T]) realNextBack() gust.Option[T] { for { if f.backiter.IsSome() { x := f.backiter.Unwrap().NextBack().InspectNone(func() { @@ -213,7 +213,7 @@ func (f *deFlattenIterator[T, D]) realNextBack() gust.Option[T] { return x } } else { - x := f.iter.NextBack().Inspect(func(t D) { + x := f.iter.NextBack().Inspect(func(t I) { f.backiter = gust.Some(FromDeIterable[T](t)) }) if x.IsNone() { @@ -228,7 +228,7 @@ func (f *deFlattenIterator[T, D]) realNextBack() gust.Option[T] { } } -func (f *deFlattenIterator[T, D]) realNext() gust.Option[T] { +func (f *deFlattenIterator[I, T]) realNext() gust.Option[T] { for { if f.frontiter.IsSome() { x := f.frontiter.Unwrap().Next().InspectNone(func() { @@ -238,7 +238,7 @@ func (f *deFlattenIterator[T, D]) realNext() gust.Option[T] { return x } } else { - x := f.iter.Next().Inspect(func(t D) { + x := f.iter.Next().Inspect(func(t I) { f.frontiter = gust.Some(FromDeIterable[T](t)) }) if x.IsNone() { @@ -253,7 +253,7 @@ func (f *deFlattenIterator[T, D]) realNext() gust.Option[T] { } } -func (f *deFlattenIterator[T, D]) realSizeHint() (uint, gust.Option[uint]) { +func (f *deFlattenIterator[I, T]) realSizeHint() (uint, gust.Option[uint]) { var fl = opt.MapOr(f.frontiter, gust.Pair[uint, gust.Option[uint]]{0, gust.Some[uint](0)}, func(i DeIterator[T]) (x gust.Pair[uint, gust.Option[uint]]) { x.A, x.B = i.SizeHint() return x @@ -271,31 +271,31 @@ func (f *deFlattenIterator[T, D]) realSizeHint() (uint, gust.Option[uint]) { return lo, gust.None[uint]() } -func (f *deFlattenIterator[T, D]) realTryFold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { +func (f *deFlattenIterator[I, T]) realTryFold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { return f.iterTryFold(init, func(acc any, item DeIterator[T]) gust.AnyCtrlFlow { return item.TryFold(acc, fold) }) } -func (f *deFlattenIterator[T, D]) realTryRfold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { +func (f *deFlattenIterator[I, T]) realTryRfold(init any, fold func(any, T) gust.AnyCtrlFlow) gust.AnyCtrlFlow { return f.iterTryRfold(init, func(acc any, item DeIterator[T]) gust.AnyCtrlFlow { return item.TryRfold(acc, fold) }) } -func (f *deFlattenIterator[T, D]) realFold(init any, fold func(any, T) any) any { +func (f *deFlattenIterator[I, T]) realFold(init any, fold func(any, T) any) any { return f.iterFold(init, func(acc any, item DeIterator[T]) any { return item.Fold(acc, fold) }) } -func (f *deFlattenIterator[T, D]) realRfold(init any, fold func(any, T) any) any { +func (f *deFlattenIterator[I, T]) realRfold(init any, fold func(any, T) any) any { return f.iterRfold(init, func(acc any, item DeIterator[T]) any { return item.Rfold(acc, fold) }) } -func (f *deFlattenIterator[T, D]) realAdvanceBy(n uint) gust.Errable[uint] { +func (f *deFlattenIterator[I, T]) realAdvanceBy(n uint) gust.Errable[uint] { var advance = func(n any, iter DeIterator[T]) gust.AnyCtrlFlow { x := iter.AdvanceBy(n.(uint)) if x.IsErr() { @@ -313,7 +313,7 @@ func (f *deFlattenIterator[T, D]) realAdvanceBy(n uint) gust.Errable[uint] { return gust.NonErrable[uint]() } -func (f *deFlattenIterator[T, D]) realAdvanceBackBy(n uint) gust.Errable[uint] { +func (f *deFlattenIterator[I, T]) realAdvanceBackBy(n uint) gust.Errable[uint] { var advance = func(n any, iter DeIterator[T]) gust.AnyCtrlFlow { x := iter.AdvanceBackBy(n.(uint)) if x.IsErr() { @@ -331,23 +331,23 @@ func (f *deFlattenIterator[T, D]) realAdvanceBackBy(n uint) gust.Errable[uint] { return gust.NonErrable[uint]() } -func (f *deFlattenIterator[T, D]) realCount() uint { +func (f *deFlattenIterator[I, T]) realCount() uint { var count = func(acc any, iter DeIterator[T]) any { return acc.(uint) + iter.Count() } return f.iterFold(uint(0), count).(uint) } -func (f *deFlattenIterator[T, D]) realLast() gust.Option[T] { +func (f *deFlattenIterator[I, T]) realLast() gust.Option[T] { var last = func(last any, iter DeIterator[T]) any { return iter.Last().Or(last.(gust.Option[T])) } return f.iterFold(gust.None[T](), last).(gust.Option[T]) } -func (f *deFlattenIterator[T, D]) iterTryFold(acc any, fold func(any, DeIterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { - var flatten = func(frontiter *gust.Option[DeIterator[T]], fold func(any, DeIterator[T]) gust.AnyCtrlFlow) func(any, D) gust.AnyCtrlFlow { - return func(acc any, iter D) gust.AnyCtrlFlow { +func (f *deFlattenIterator[I, T]) iterTryFold(acc any, fold func(any, DeIterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { + var flatten = func(frontiter *gust.Option[DeIterator[T]], fold func(any, DeIterator[T]) gust.AnyCtrlFlow) func(any, I) gust.AnyCtrlFlow { + return func(acc any, iter I) gust.AnyCtrlFlow { return fold(acc, *frontiter.Insert(FromDeIterable[T](iter))) } } @@ -374,11 +374,11 @@ func (f *deFlattenIterator[T, D]) iterTryFold(acc any, fold func(any, DeIterator return gust.AnyContinue(acc) } -func (f *deFlattenIterator[T, D]) iterFold(acc any, fold func(any, DeIterator[T]) any) any { +func (f *deFlattenIterator[I, T]) iterFold(acc any, fold func(any, DeIterator[T]) any) any { f.frontiter.Inspect(func(i DeIterator[T]) { acc = fold(acc, i) }) - acc = f.iter.Fold(acc, func(acc any, i D) any { + acc = f.iter.Fold(acc, func(acc any, i I) any { return fold(acc, FromDeIterable[T](i)) }) f.backiter.Inspect(func(i DeIterator[T]) { @@ -387,9 +387,9 @@ func (f *deFlattenIterator[T, D]) iterFold(acc any, fold func(any, DeIterator[T] return acc } -func (f *deFlattenIterator[T, D]) iterTryRfold(acc any, fold func(any, DeIterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { - var flatten = func(backiter *gust.Option[DeIterator[T]], fold func(any, DeIterator[T]) gust.AnyCtrlFlow) func(any, D) gust.AnyCtrlFlow { - return func(acc any, iter D) gust.AnyCtrlFlow { +func (f *deFlattenIterator[I, T]) iterTryRfold(acc any, fold func(any, DeIterator[T]) gust.AnyCtrlFlow) gust.AnyCtrlFlow { + var flatten = func(backiter *gust.Option[DeIterator[T]], fold func(any, DeIterator[T]) gust.AnyCtrlFlow) func(any, I) gust.AnyCtrlFlow { + return func(acc any, iter I) gust.AnyCtrlFlow { return fold(acc, *backiter.Insert(FromDeIterable[T](iter))) } } @@ -416,11 +416,11 @@ func (f *deFlattenIterator[T, D]) iterTryRfold(acc any, fold func(any, DeIterato return gust.AnyContinue(acc) } -func (f *deFlattenIterator[T, D]) iterRfold(acc any, fold func(any, DeIterator[T]) any) any { +func (f *deFlattenIterator[I, T]) iterRfold(acc any, fold func(any, DeIterator[T]) any) any { f.backiter.Inspect(func(i DeIterator[T]) { acc = fold(acc, i) }) - acc = f.iter.Rfold(acc, func(acc any, i D) any { + acc = f.iter.Rfold(acc, func(acc any, i I) any { return fold(acc, FromDeIterable[T](i)) }) f.frontiter.Inspect(func(i DeIterator[T]) {