Skip to content

Commit

Permalink
chore(iter): update Flatten
Browse files Browse the repository at this point in the history
  • Loading branch information
andeya committed Sep 7, 2022
1 parent 0916769 commit 9bb1e4d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 73 deletions.
17 changes: 17 additions & 0 deletions examples/iterator/flatten_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
2 changes: 1 addition & 1 deletion examples/overview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)) },
Expand Down
8 changes: 4 additions & 4 deletions iter/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
136 changes: 68 additions & 68 deletions iter/iter_flatten.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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() {
Expand All @@ -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
Expand All @@ -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)))
}
}
Expand All @@ -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]) {
Expand All @@ -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() {
Expand All @@ -162,48 +162,48 @@ 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]))
}
return f.iterFold(gust.None[T](), last).(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() {
Expand All @@ -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() {
Expand All @@ -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() {
Expand All @@ -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() {
Expand All @@ -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
Expand All @@ -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() {
Expand All @@ -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() {
Expand All @@ -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)))
}
}
Expand All @@ -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]) {
Expand All @@ -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)))
}
}
Expand All @@ -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]) {
Expand Down

0 comments on commit 9bb1e4d

Please sign in to comment.