Skip to content

Commit

Permalink
Add iterator functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ismail Gjevori committed Mar 21, 2022
1 parent a7a8049 commit 45579e5
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/isgj/collection

go 1.18

require golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 h1:ba9YlqfDGTTQ5aZ2fwOoQ1hf32QySyQkR6ODGDzHlnE=
golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
67 changes: 67 additions & 0 deletions iter/iterators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Utility iterator functions.
package iter

import (
c "github.com/isgj/collection"
"golang.org/x/exp/constraints"
)

// Map will map values of type `I` from to type `O` through the `to` mapper function.
//
// Example:
// v := collection.Vec[int]{1, 2, 3, 4, 5, 6, 7, 8, 9}
// number_iterator := v.Iter().Filter(func(item int) string { return item%2 == 0})
// iter.Map(number_iterator, func(item int) string { return fmt.Sprint("number ", item) }).
// ForEach(func(item string) { fmt.Prinln(item) })
//
// This is a workaround to implement `Map` as currently methods cannot have type paramters.
func Map[I any, O any](it c.Iterator[I], to func(item I) O) c.Iterator[O] {
return func() (O, bool) {
if i, ok := it(); ok {
return to(i), true
}
return *new(O), false
}
}

// Reduce will reduce the values through the reducer
//
// This is a workaround to implement `Reduce` as currently methods cannot have type paramters.
func Reduce[I any, O any](it c.Iterator[I], start O, reducer func(acc O, item I) O) O {
for i, ok := it(); ok; i, ok = it() {
start = reducer(start, i)
}
return start
}

// Sum will return the sum of the values. If the iterated values are strings it will concatenate them
func Sum[T constraints.Ordered](it c.Iterator[T]) T {
result, _ := it()
for i, ok := it(); ok; i, ok = it() {
result += i
}
return result
}

func FromSlice[T any](s []T) c.Iterator[T] {
return c.Vec[T](s).Iter()
}

// Iterate from 0 to `end` by steps of 1
func Range(end int) c.Iterator[int] {
return XRange(0, end, 1)
}

// Iterate from `start` to `end` by steps of `step`.
// Currently the range will only increase, the step will be added for each iteration so make sure that it will
// eventually reach the end, otherwise you enter an infinite loop.
func XRange(start, end, step int) c.Iterator[int] {
return func() (int, bool) {
if start < end {
r := start
start += step
return r, true
}
return 0, false
}
}

0 comments on commit 45579e5

Please # to comment.