Skip to content

Commit 7f1e57f

Browse files
committed
Move chaining iterators to itx package
1 parent 84d6998 commit 7f1e57f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+585
-313
lines changed

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ A library of iterators for use with `iter.Seq`. Requires Go 1.23+.
77
```go
88
// The first 5 natural numbers
99
numbers := slices.Collect(
10-
it.Take(it.Count(), 5),
10+
it.Take(it.Count[int](), 5),
1111
)
1212

1313
// All even numbers
14-
evens := it.Filter(it.Count(), filter.IsEven)
14+
evens := it.Filter(it.Count[int](), filter.IsEven)
1515

1616
// String representations of integers
17-
numbers := it.Map(it.Count(), strconv.Itoa)
17+
numbers := it.Map(it.Count[int](), strconv.Itoa)
1818
```
1919

2020
_[Read the docs](https://pkg.go.dev/github.com/BooleanCat/go-functional/v2)_ to see the full iterator library.
@@ -24,3 +24,22 @@ _[Read the docs](https://pkg.go.dev/github.com/BooleanCat/go-functional/v2)_ to
2424
```terminal
2525
go get github.com/BooleanCat/go-functional/v2@latest
2626
```
27+
28+
## Iterator Chaining
29+
30+
The iterators in this package were designed to be used with the native
31+
`iter.Seq` from Go's standard library. In order to facilitate complex
32+
sequences of iterators, the
33+
[`itx`](https://github.com/BooleanCat/go-functional/tree/main/it/itx) package
34+
provides `Iterator` and `Iterator2` as wrappers around `iter.Seq` and
35+
`iter.Seq2` that allow for chaining operations.
36+
37+
Let's take a look at an example:
38+
39+
```go
40+
// The first 10 odd integers
41+
itx.Count[int]().Filter(filter.IsOdd).Take(10).Collect()
42+
```
43+
44+
Most iterators support chaining. A notable exception is `it.Map` which cannot
45+
support chaining due to limitations on Go's type system.

it/chain.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ func Chain[V any](iterators ...iter.Seq[V]) iter.Seq[V] {
1111
}
1212
}
1313

14-
// Chain is a convenience method for chaining [Chain] on [Iterator]s.
15-
func (iterator Iterator[V]) Chain(iterators ...iter.Seq[V]) Iterator[V] {
16-
return Iterator[V](Chain[V](append([]iter.Seq[V]{iter.Seq[V](iterator)}, iterators...)...))
17-
}
18-
1914
// Chain2 yields values from multiple iterators in sequence.
2015
func Chain2[V, W any](iterators ...iter.Seq2[V, W]) iter.Seq2[V, W] {
2116
return func(yield func(V, W) bool) {
@@ -24,8 +19,3 @@ func Chain2[V, W any](iterators ...iter.Seq2[V, W]) iter.Seq2[V, W] {
2419
}
2520
}
2621
}
27-
28-
// Chain is a convenience method for chaining [Chain2] on [Iterator2]s.
29-
func (iterator Iterator2[V, W]) Chain(iterators ...iter.Seq2[V, W]) Iterator2[V, W] {
30-
return Iterator2[V, W](Chain2(append([]iter.Seq2[V, W]{iter.Seq2[V, W](iterator)}, iterators...)...))
31-
}

it/chain_test.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@ func ExampleChain() {
1818
// Output: [1 2 3 4]
1919
}
2020

21-
func ExampleChain_method() {
22-
numbers := it.Iterator[int](slices.Values([]int{1, 2})).Chain(slices.Values([]int{3, 4})).Collect()
23-
24-
fmt.Println(numbers)
25-
// Output: [1 2 3 4]
26-
}
27-
2821
func TestChainEmpty(t *testing.T) {
2922
t.Parallel()
3023

@@ -57,13 +50,6 @@ func ExampleChain2() {
5750
// Output: 2
5851
}
5952

60-
func ExampleChain2_method() {
61-
pairs := it.Iterator2[string, int](maps.All(map[string]int{"a": 1})).Chain(maps.All(map[string]int{"b": 2}))
62-
63-
fmt.Println(len(maps.Collect(iter.Seq2[string, int](pairs))))
64-
// Output: 2
65-
}
66-
6753
func TestChain2(t *testing.T) {
6854
t.Parallel()
6955

it/channel.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,3 @@ func ToChannel[V any](seq iter.Seq[V]) <-chan V {
3333

3434
return channel
3535
}
36-
37-
// ToChannel is a convenience method for chaining [ToChannel] on [Iterator]s.
38-
func (iterator Iterator[V]) ToChannel() <-chan V {
39-
return ToChannel(iter.Seq[V](iterator))
40-
}

it/channel_test.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,6 @@ func ExampleToChannel() {
6666
// 3
6767
}
6868

69-
func ExampleToChannel_method() {
70-
channel := it.Iterator[int](slices.Values([]int{1, 2, 3})).ToChannel()
71-
72-
for number := range channel {
73-
fmt.Println(number)
74-
}
75-
76-
// Output:
77-
// 1
78-
// 2
79-
// 3
80-
}
81-
8269
func TestToChannelEmpty(t *testing.T) {
8370
t.Parallel()
8471

it/cycle.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ func Cycle[V any](delegate iter.Seq[V]) iter.Seq[V] {
2929
}
3030
}
3131

32-
// Cycle is a convenience method for chaining [Cycle] on [Iterator]s.
33-
func (iterator Iterator[V]) Cycle() Iterator[V] {
34-
return Iterator[V](Cycle(iter.Seq[V](iterator)))
35-
}
36-
3732
// Cycle2 yields pairs of values from an iterator repeatedly.
3833
//
3934
// Note: this is an infinite iterator.
@@ -66,8 +61,3 @@ func Cycle2[V, W any](delegate iter.Seq2[V, W]) iter.Seq2[V, W] {
6661
}
6762
}
6863
}
69-
70-
// Cycle is a convenience method for chaining [Cycle2] on [Iterator2]s.
71-
func (iterator Iterator2[V, W]) Cycle() Iterator2[V, W] {
72-
return Iterator2[V, W](Cycle2(iter.Seq2[V, W](iterator)))
73-
}

it/cycle_test.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package it_test
22

33
import (
44
"fmt"
5-
"iter"
65
"maps"
76
"slices"
87
"testing"
@@ -18,13 +17,6 @@ func ExampleCycle() {
1817
// Output: [1 2 1 2 1]
1918
}
2019

21-
func ExampleCycle_method() {
22-
numbers := it.Iterator[int](slices.Values([]int{1, 2})).Cycle().Take(5).Collect()
23-
24-
fmt.Println(numbers)
25-
// Output: [1 2 1 2 1]
26-
}
27-
2820
func TestCycleYieldFalse(t *testing.T) {
2921
t.Parallel()
3022

@@ -44,13 +36,6 @@ func ExampleCycle2() {
4436
// Output: map[1:one]
4537
}
4638

47-
func ExampleCycle2_method() {
48-
numbers := it.Iterator2[int, string](maps.All(map[int]string{1: "one"})).Cycle().Take(5)
49-
50-
fmt.Println(maps.Collect(iter.Seq2[int, string](numbers)))
51-
// Output: map[1:one]
52-
}
53-
5439
func TestCycle2YieldFalse(t *testing.T) {
5540
t.Parallel()
5641

it/drop.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ func Drop[V any](delegate iter.Seq[V], count int) iter.Seq[V] {
1919
}
2020
}
2121

22-
// Drop is a convenience method for chaining [Drop] on [Iterator]s.
23-
func (iterator Iterator[V]) Drop(count int) Iterator[V] {
24-
return Iterator[V](Drop(iter.Seq[V](iterator), count))
25-
}
26-
2722
// Drop2 yields all pairs of values from a delegate [Iterator2] except the
2823
// first `count` pairs.
2924
func Drop2[V, W any](delegate iter.Seq2[V, W], count int) iter.Seq2[V, W] {
@@ -40,8 +35,3 @@ func Drop2[V, W any](delegate iter.Seq2[V, W], count int) iter.Seq2[V, W] {
4035
}
4136
}
4237
}
43-
44-
// Drop is a convenience method for chaining [Drop] on [Iterator2]s.
45-
func (iterator Iterator2[V, W]) Drop(count int) Iterator2[V, W] {
46-
return Iterator2[V, W](Drop2(iter.Seq2[V, W](iterator), count))
47-
}

it/drop_test.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package it_test
22

33
import (
44
"fmt"
5-
"iter"
65
"maps"
76
"slices"
87
"testing"
@@ -22,17 +21,6 @@ func ExampleDrop() {
2221
// 5
2322
}
2423

25-
func ExampleDrop_method() {
26-
for value := range it.Iterator[int](slices.Values([]int{1, 2, 3, 4, 5})).Drop(2) {
27-
fmt.Println(value)
28-
}
29-
30-
// Output:
31-
// 3
32-
// 4
33-
// 5
34-
}
35-
3624
func TestDropYieldFalse(t *testing.T) {
3725
t.Parallel()
3826

@@ -58,13 +46,6 @@ func ExampleDrop2() {
5846
// Output: 2
5947
}
6048

61-
func ExampleDrop2_method() {
62-
numbers := it.Iterator2[int, string](maps.All(map[int]string{1: "one", 2: "two", 3: "three"})).Drop(1)
63-
64-
fmt.Println(len(maps.Collect(iter.Seq2[int, string](numbers))))
65-
// Output: 2
66-
}
67-
6849
func TestDrop2(t *testing.T) {
6950
t.Parallel()
7051

it/enumerate.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,3 @@ func Enumerate[V any](delegate iter.Seq[V]) iter.Seq2[int, V] {
1717
}
1818
}
1919
}
20-
21-
// Enumerate is a convenience method for chaining [Enumerate] on [Iterator]s.
22-
func (iterator Iterator[V]) Enumerate() Iterator2[int, V] {
23-
return Iterator2[int, V](Enumerate[V](iter.Seq[V](iterator)))
24-
}

0 commit comments

Comments
 (0)