Skip to content

Commit c6c878a

Browse files
committed
feat(Zip): implement stream zipping
1 parent 9c656db commit c6c878a

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

zip.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package fungi
2+
3+
// Zip two streams using a custom zipper function. Just like similar operations
4+
// in other languages, zipping will stop on error from either one of the source
5+
// streams. Therefore, if one of the source streams is shorter than the other,
6+
// the resulting stream is going to contain as many elements as the shorter
7+
// source stream.
8+
func Zip[T, R, O any](zipper func(T, R) O) func(Stream[T]) StreamTransformer[R, O] {
9+
return func(itemsT Stream[T]) StreamTransformer[R, O] {
10+
return func(itemsR Stream[R]) Stream[O] {
11+
return &zip[T, R, O]{
12+
ts: itemsT,
13+
rs: itemsR,
14+
zipper: zipper,
15+
}
16+
}
17+
}
18+
}
19+
20+
type zip[T, R, O any] struct {
21+
ts Stream[T]
22+
rs Stream[R]
23+
zipper func(T, R) O
24+
}
25+
26+
func (z *zip[T, R, O]) Next() (item O, err error) {
27+
t, err := z.ts.Next()
28+
if err != nil {
29+
return
30+
}
31+
r, err := z.rs.Next()
32+
if err != nil {
33+
return
34+
}
35+
return z.zipper(t, r), nil
36+
}

zip_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package fungi
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestZip(t *testing.T) {
10+
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
11+
ts := SliceStream(slice)
12+
rs := SliceStream(slice)
13+
zip := Zip(add)
14+
stream := zip(ts)(rs)
15+
result, err := CollectSlice(stream)
16+
assert.NoError(t, err)
17+
assert.Equal(t, []int{2, 4, 6, 8, 10, 12, 14, 16, 18, 20}, result)
18+
}

0 commit comments

Comments
 (0)