Skip to content

Commit

Permalink
Add Transform iter to itx
Browse files Browse the repository at this point in the history
Transform is a limited form of Map where the argument type is the same as
the return type, allowing it to be chained.
  • Loading branch information
BooleanCat committed Jul 19, 2024
1 parent 56afa4a commit e8c6305
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
21 changes: 21 additions & 0 deletions it/itx/map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package itx

import "github.com/BooleanCat/go-functional/v2/it"

// Transform is a convenience method for chaining [it.Map] on [Iterator]s where
// the provided functions argument type is the same as its return type.
//
// This is a limited version of [it.Map] due to a limitation on Go's type
// system whereby new generic type parameters cannot be defined on methods.
func (iterator Iterator[V]) Transform(f func(V) V) Iterator[V] {
return Iterator[V](it.Map(iterator, f))
}

// Transform is a convenience method for chaining [it.Map2] on [Iterator2]s
// where the provided functions argument type is the same as its return type.
//
// This is a limited version of [it.Map2] due to a limitation on Go's type
// system whereby new generic type parameters cannot be defined on methods.
func (iterator Iterator2[V, W]) Transform(f func(V, W) (V, W)) Iterator2[V, W] {
return Iterator2[V, W](it.Map2(iterator, f))
}
24 changes: 24 additions & 0 deletions it/itx/map_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package itx_test

import (
"fmt"
"maps"

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

func ExampleIterator_Transform() {
fmt.Println(itx.FromSlice([]int{0, 1, 2}).Transform(func(v int) int {
return v + 1
}).Collect())
// Output: [1 2 3]
}

func ExampleIterator2_Transform() {
addOne := func(a, b int) (int, int) {
return a + 1, b + 1
}

fmt.Println(maps.Collect(itx.FromMap(map[int]int{1: 2}).Transform(addOne).Seq()))
// Output: map[2:3]
}
15 changes: 8 additions & 7 deletions it/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ package it

import "iter"

// Map yields values from an iterator that have been transformed by a function.
func Map[V, W any](delegate func(func(V) bool), transform func(V) W) iter.Seq[W] {
// Map yields values from an iterator that have had the provided function
// applied to each value.
func Map[V, W any](delegate func(func(V) bool), f func(V) W) iter.Seq[W] {
return func(yield func(W) bool) {
for value := range delegate {
if !yield(transform(value)) {
if !yield(f(value)) {
return
}
}
}
}

// Map2 yields pairs of values from an iterator that have been transformed by a
// function.
func Map2[V, W, X, Y any](delegate func(func(V, W) bool), transform func(V, W) (X, Y)) iter.Seq2[X, Y] {
// Map2 yields pairs of values from an iterator that have had the provided
// function applied to each pair.
func Map2[V, W, X, Y any](delegate func(func(V, W) bool), f func(V, W) (X, Y)) iter.Seq2[X, Y] {
return func(yield func(X, Y) bool) {
for v, w := range delegate {
if !yield(transform(v, w)) {
if !yield(f(v, w)) {
return
}
}
Expand Down

0 comments on commit e8c6305

Please sign in to comment.