Skip to content

Commit

Permalink
Add Drain consumer
Browse files Browse the repository at this point in the history
  • Loading branch information
BooleanCat committed Sep 9, 2024
1 parent 50bcb91 commit 0563dae
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 0 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,38 @@ for number := range channel {
> Unlike most consumers, the iterator is not immediately consumed by ToChannel. Instead is it
> consumed as values are pulled from the channel.
### Drain

Drain consumes an iterator's values and drops them.

```go
printValue := func(n int) int {
fmt.Println(n)
return n
}

it.Drain(it.Map(slices.Values([]int{1, 2, 3}), printValue))

// Chainable
itx.From(it.Map(slices.Values([]int{1, 2, 3}), printValue)).Drain()

// Drain an iter.Seq2
printValue2 := func(i, n int) (int, int) {
fmt.Println(n)
return i, n
}

it.Drain2(it.Map2(slices.All([]int{1, 2, 3}), printValue2))

// As above, but chainable
itx.From2(it.Map2(slices.All([]int{1, 2, 3}), printValue2)).Drain()
```

<!-- prettier-ignore -->
> [!TIP]
> Use Drain to consume an iterator to invoke any side effects when you don't need to collect the
> values.
## Iterators

This library contains two kinds of iterators in the `it` and `itx` packages. In most cases you'll
Expand Down
18 changes: 18 additions & 0 deletions it/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,21 @@ func Contains[V comparable](iterator func(func(V) bool), v V) bool {

return false
}

// Drain consumes an [iter.Seq] completely, dropping all values.
//
// You may wish to use this to execute side effects without needing to collect
// values.
func Drain[V any](iterator func(func(V) bool)) {
for range iterator {
}
}

// Drain2 consumes an [iter.Seq2] completely, dropping all values.
//
// You may wish to use this to execute side effects without needing to collect
// values.
func Drain2[V, W any](iterator func(func(V, W) bool)) {
for range iterator {
}
}
28 changes: 28 additions & 0 deletions it/iter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,31 @@ func ExampleContains() {
func TestContainsFalse(t *testing.T) {
assert.False(t, it.Contains(slices.Values([]int{1, 2, 3}), 4))
}

func ExampleDrain() {
numbers := it.Map(slices.Values([]int{1, 2, 3}), func(n int) int {
fmt.Println(n)
return n
})

it.Drain(numbers)

// Output:
// 1
// 2
// 3
}

func ExampleDrain2() {
numbers := it.Map2(slices.All([]int{1, 2, 3}), func(i, n int) (int, int) {
fmt.Println(n)
return i, n
})

it.Drain2(numbers)

// Output:
// 1
// 2
// 3
}
10 changes: 10 additions & 0 deletions it/itx/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,13 @@ func (iterator Iterator[V]) Len() int {
func (iterator Iterator2[V, W]) Len() int {
return it.Len2(iterator)
}

// Drain is a convenience method for chaining [it.Drain] on [Iterator]s.
func (iterator Iterator[V]) Drain() {
it.Drain(iterator)
}

// Drain2 is a convenience method for chaining [it.Drain2] on [Iterator2]s.
func (iterator Iterator2[V, W]) Drain() {
it.Drain2(iterator)
}
25 changes: 25 additions & 0 deletions it/itx/iter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"maps"
"slices"

"github.com/BooleanCat/go-functional/v2/it"
"github.com/BooleanCat/go-functional/v2/it/itx"
)

Expand Down Expand Up @@ -97,3 +98,27 @@ func ExampleIterator2_Len() {
fmt.Println(itx.FromSlice([]int{1, 2, 3}).Enumerate().Len())
// Output: 3
}

func ExampleIterator_Drain() {
itx.From(it.Map(slices.Values([]int{1, 2, 3}), func(n int) int {
fmt.Println(n)
return n
})).Drain()

// Output:
// 1
// 2
// 3
}

func ExampleIterator2_Drain() {
itx.From2(it.Map2(slices.All([]int{1, 2, 3}), func(i, n int) (int, int) {
fmt.Println(n)
return i, n
})).Drain()

// Output:
// 1
// 2
// 3
}

0 comments on commit 0563dae

Please sign in to comment.