Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 12 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,7 @@ for line, err := range it.LinesString(buffer) {
<h3 id="map">Map & Transform</h3

Map yields values from an iterator that have had the provided function applied to each value.
Transform serves the same purpose but contrains the return type to the type of the iterator's values
(see note below).
Transform (older version before Go 1.27) serves the same purpose but constrains the return type to the type of the iterator's values.

```go
double := func(n int) int { return n * 2 }
Expand All @@ -696,30 +695,16 @@ doubleBoth := func(n, m int) (int, int) { return n * 2, m * 2 }

it.Map2(maps.All(map[int]int{1: 2, 3: 4}), doubleBoth)

// Limited chainable flavour of Map
itx.FromSlice([]int{0, 1, 2}).Transform(double)
// chainable flavour of Map
itx.FromSlice([]int{0, 1, 2}).Map(double)

// As above for iter.Seq2
itx.FromMap(map[int]int{1: 2}).Transform(doubleBoth)
itx.FromMap(map[int]int{1: 2}).Map(doubleBoth)
```

<!-- prettier-ignore -->
> [!NOTE]
> The `itx` package does not contain `Map` due to limitations with Go's type system. Instead a
> limited from of `Map` called `Transform` is provided where the type returned from operations is
> the same as a type of the iterator's values.
>
> A chainable Map will be added should Go's type system ever support new generic type parameters on
> methods.

<!-- prettier-ignore -->
> [!TIP]
> If you wish to chain operations on `Map`, you can do so by first converting it to an
> `itx.Iterator` like so:
>
> ```go
> itx.From(it.Map(slices.Values([]int{1, 2, 3}), double)).Collect()
> ```
-<!-- prettier-ignore -->
> [!WARNING]
> Transform will be removed in later versions and clients should transition to Map.

### MapError & TransformError

Expand All @@ -731,27 +716,13 @@ double := func(n int, err error) int { return n * 2, nil }

it.MapError(slices.Values([]int{1, 2, 3}), double)

// Limited chainable flavour of MapError
itx.FromSlice([]int{1, 2, 3}).TransformError(double)
// chainable flavour of MapError
itx.FromSlice([]int{1, 2, 3}).MapError(double)
```

<!-- prettier-ignore -->
> [!NOTE]
> The `itx` package does not contain `MapError` due to limitations with Go's type system. Instead a
> limited from of `MapError` called `TransformError` is provided where the type returned from
> operations is the same as a type of the iterator's values.
>
> A chainable MapError will be added should Go's type system ever support new generic type
> parameters on methods.

<!-- prettier-ignore -->
> [!TIP]
> If you wish to chain operations on `MapError`, you can do so by first converting it to an
> `itx.Iterator2` like so:
>
> ```go
> itx.From2(it.MapError(slices.Values([]int{1, 2, 3}), double)).Collect()
> ```
-<!-- prettier-ignore -->
> [!WARNING]
> TransformError will be removed in later versions and clients should transition to MapError.

### NaturalNumbers

Expand Down
12 changes: 9 additions & 3 deletions it/itx/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import "github.com/BooleanCat/go-functional/v2/it"
// 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.
// system before Go 1.27 whereby new generic type parameters cannot be defined on methods.
//
// Deprecated: This will be removed in later versions and clients should transition to [Iterator.Map].
func (iterator Iterator[V]) Transform(f func(V) V) Iterator[V] {
return Iterator[V](it.Map(iterator, f))
}
Expand All @@ -15,7 +17,9 @@ func (iterator Iterator[V]) Transform(f func(V) V) Iterator[V] {
// 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.
// system before Go 1.27 whereby new generic type parameters cannot be defined on methods.
//
// Deprecated: This will be removed in later versions and clients should transition to [Iterator2.Map].
func (iterator Iterator2[V, W]) Transform(f func(V, W) (V, W)) Iterator2[V, W] {
return Iterator2[V, W](it.Map2(iterator, f))
}
Expand All @@ -25,7 +29,9 @@ func (iterator Iterator2[V, W]) Transform(f func(V, W) (V, W)) Iterator2[V, W] {
// return type.
//
// This is a limited version of [it.MapError] due to a limitation on Go's type
// system whereby new generic type parameters cannot be defined on methods.
// system before Go 1.27 whereby new generic type parameters cannot be defined on methods.
//
// Deprecated: This will be removed in later versions and clients should transition to [Iterator.MapError].
func (iterator Iterator[V]) TransformError(f func(V) (V, error)) Iterator2[V, error] {
return Iterator2[V, error](it.MapError(iterator, f))
}
20 changes: 20 additions & 0 deletions it/itx/map_go_127.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build go1.27

package itx

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

// Map is a convenience method for chaining [it.Map] on [Iterator]s.
func (iterator Iterator[V]) Map[W any](f func(V) W) Iterator[W] {
return Iterator[W](it.Map(iterator, f))
}

// Map is a convenience method for chaining [it.Map2] on [Iterator2]s.
func (iterator Iterator2[V, W]) Map[X, Y any](f func(V, W) (X, Y)) Iterator2[X, Y] {
return Iterator2[X, Y](it.Map2(iterator, f))
}

// MapError is a convenience method for chaining [it.MapError] on [Iterator]s.
func (iterator Iterator[V]) MapError[W any](f func(V) (W, error)) Iterator2[W, error] {
return Iterator2[W, error](it.MapError(iterator, f))
}
34 changes: 34 additions & 0 deletions it/itx/map_go_127_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//go:build go1.27

package itx_test

import (
"fmt"
"maps"

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

func ExampleIterator_Map() {
fmt.Println(itx.FromSlice([]string{"", "a", "aa"}).Map(func(v string) int {
return len(v)
}).Collect())
// Output: [0 1 2]
}

func ExampleIterator2_Map() {
count := func(a, b string) (string, int) {
return a, len(b)
}

fmt.Println(maps.Collect(itx.FromMap(map[string]string{"k1": "a", "k2": "aa"}).Map(count).Seq()))
// Output: map[k1:1 k2:2]
}

func ExampleIterator_MapError() {
fmt.Println(it.TryCollect(itx.FromSlice([]string{"", "a", "aa"}).MapError(func(v string) (int, error) {
return len(v), nil
})))
// Output: [0 1 2] <nil>
}