From e8c630560edf5f306cb86d818b2f785dead5119d Mon Sep 17 00:00:00 2001 From: Tom Godkin Date: Fri, 19 Jul 2024 14:37:59 +0100 Subject: [PATCH] Add Transform iter to itx Transform is a limited form of Map where the argument type is the same as the return type, allowing it to be chained. --- it/itx/map.go | 21 +++++++++++++++++++++ it/itx/map_test.go | 24 ++++++++++++++++++++++++ it/map.go | 15 ++++++++------- 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 it/itx/map.go create mode 100644 it/itx/map_test.go diff --git a/it/itx/map.go b/it/itx/map.go new file mode 100644 index 0000000..8f53641 --- /dev/null +++ b/it/itx/map.go @@ -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)) +} diff --git a/it/itx/map_test.go b/it/itx/map_test.go new file mode 100644 index 0000000..360629b --- /dev/null +++ b/it/itx/map_test.go @@ -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] +} diff --git a/it/map.go b/it/map.go index f88c201..1a9361e 100644 --- a/it/map.go +++ b/it/map.go @@ -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 } }