iter

package module
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2023 License: MIT Imports: 6 Imported by: 0

README

Iteration library in go

This package provides generic iterators and iterator transformations in go.

Iterators defer iteration execution by pushing iteration logic into the Next() function.

This package has a dependency on go-types for the Option[T any] type. Users of the iter module can utilize Result[T] to capture errors or perform transformations on slices that can contain errors.

Looping

Here are three ways to loop over an iterator

For Loop

A for loop has init, condition and post sections that can be used on an iterator.

rng := iter.Range(0, 10)
for op := rng.Next(); op.IsSome(); op = rng.Next() {
    // code in here
}

Async (calling range on a channel)

You can also loop over a channel created from an Iterator[T] using the iter.Async function. You can specify a context with the iter.WithContext[T] option. If no context is specified, context.Background() is used.

rng := iter.Range(0, 10)
for value := range iter.Async(rng) {
    // code in here
}

Specify a context

rng := iter.Range(0,10)
op := iter.WithContext[int](context.TODO())
for value := range iter.Async(rng, op){
    // code here
}

ForEach

ForEach uses an anonymous function to iterate over each item to the caller.

rng := iter.Range(0, 10)
iter.ForEach(rng, func(i int) {
    fmt.Print(" ")
    fmt.Print(i)
})
// prints:
//  0 1 2 3 4 5 6 7 8 9

ForEachIndex

ForEachIndex uses an anonymous function to iterate over each item and the index of that item to the caller.

rng := iter.Range(0, 10)
iter.ForEachIndex(rng, func(index int, i int) {
    if index > 0 {
        fmt.Print(" ")
    }
    fmt.Print(i)
})
// prints:
// 0 1 2 3 4 5 6 7 8 9

Range

The Range function creates an iterator over [begin..end) (inclusive begin, exclusive end)

rng := iter.Range(0, 10)
iter.ForEachIndex(rng, func(index int, i int) {
    if index > 0 {
        fmt.Print(" ")
    }
    fmt.Print(i)
})
// prints:
// 0 1 2 3 4 5 6 7 8 9

RangeWith

The RangeWith function creates an iterator over the range begin..end. The includeBegin and includeEnd flags control if the range is inclusive start and inclusive end.

rng := iter.RangeWith(false, 0, 10, true)
iter.ForEachIndex(rng, func(index int, i int) {
    if index > 0 {
        fmt.Print(" ")
    }
    fmt.Print(i)
})
// prints:
// 1 2 3 4 5 6 7 8 9 10

Repeat

Repeat returns an iterator that repeats the given element, count times

rep := iter.Repeat(10, 5)
iter.ForEachIndex(rng, func(index int, i int) {
    if index > 0 {
        fmt.Print(" ")
    }
    fmt.Print(i)
})
// prints:
// 10 10 10 10 10

Select

The Select function transforms an iterator of one type to an iterator of another type.

rng := iter.Range(0,10)
strRng := iter.Select(rng, strconv.Itoa)
iter.ForEachIndex(strRng, func(index int, s string){
    if index > 0{
        fmt.Print(" ")
    }
    fmt.Print("'%s'", s)
})
// prints : '0' '1' '2' '3' '4' '5' '6' '7' '8' '9'

Where

The Where function removes items from an iterator using a predicate function.

rng := iter.Range(0,10)
even := func(i int){ return i % 2 }
evens := iter.Where(rng, even)
iter.ForEachIndex(evens, func(index int, i int){
    if index > 0{
        fmt.Print(" ")
    }
    fmt.Print("%d", i)
})
// prints : 0 2 4 6 8

FromSlice

The FromSlice function returns a slice iterator over the given slice

slice := []int{1, 3, 5, 7, 9}
it := iter.FromSlice(slice)
iter.ForEachIndex(it, func(index int, i int){
    if index > 0{
        fmt.Print(" ")
    }
    fmt.Print("%d", i)
})
// prints 1 3 5 7 9

ToSlice

The ToSlice function returns a slice from the given iterator by iterating over all elements.

rng := iter.Range(0, 10)
slice := iter.ToSlice(rng)
fmt.Println(slice)
// prints : [0 1 2 3 4 5 6 7 8 9]

FromMap

The FromMap function returns an iterator over the given map. FromMap captures keys of the map in the first call to Next(). Subsequent calls to Next() track an index into the key slice to return the next key value pair. Each call to Next() returns an Option tuple of Key Value pairs.

m := map[string]int{"0":0, "1":1, "2":2, "3":3}
it := iter.FromMap(m)
fmt.Print("[ ")
iter.ForEachIndex(it, func(index int, tup types.Tuple2[string, int]){
    if index > 0{
        fmt.Print(", ")
    }    
    k, v := tup.Deconstruct()
    fmt.Print("'%s':%d", k, v)
})
fmt.Print(" ]")
// prints : [ '0':0, '1':1, '2':2, '3':3 ]

FromMapAsync

The FromMapAsync function returns an iterator over the given map using channels and the supplied context. FromMapAsync uses a go routine to iterate over the map and channels to capture the key value pair. The Next() function removes a tuple key, value from the channel.

m := map[string]int{"0":0, "1":1, "2":2, "3":3}
it := iter.FromMapAsync(m, context.Background())
fmt.Print("[ ")
iter.ForEachIndex(it, func(index int, tup types.Tuple2[string, int]){
    if index > 0{
        fmt.Print(", ")
    }    
    k, v := tup.Deconstruct()
    fmt.Print("'%s':%d", k, v)
})
fmt.Print(" ]")
// prints : [ '0':0, '1':1, '2':2, '3':3 ]

Count

The Count function returns the count of element in the iterator by iterating over all the elements.

expected := 10
rng := iter.Range(0, expected)
actual := iter.Count(rng)
if actual != expected {
    t.Fatalf("expected count of %d but found %d", expected, actual)
}

FromChannel

The FromChannel function returns an iterator over the given channel. A context can be specified in options for early termination.

ch := make(chan int)
go func(c chan int) {
    defer close(c)
    for i := 0; i < 10; i++ {
        ch <- i
    }
}(ch)
it := iter.FromChannel(ch)
iter.ForEach(it, func(i int) {
    fmt.Println(i)
})

First

First returns the first item in the sequence. If the sequence has no more items, First returns types.None[T]

sequence := iter.Range(15, 30)
first := iter.First(sequence)
switch op := first.(type) {
case types.Some[int]:
    fmt.Println(op.Value)
case types.None[int]:
    fmt.Println("none")
}
// prints 
// 15

FirstWhere

FirstWhere returns the first item in the sequence that matches the condition. If the sequence has no more items or no matches exist, First returns types.None[T]

sequence := iter.Range(15, 30)
first := iter.FirstWhere(sequence, func(i int)bool{ return i % 10 == 0})
switch op := first.(type) {
case types.Some[int]:
    fmt.Println(op.Value)
case types.None[int]:
    fmt.Println("none")
}
// prints
// 20

Documentation

Overview

This package provides generic iterators and iterator transformations in go.

Iterators defer iteration execution by pushing iteration logic into the Next() function.

This package has a dependency on [go-types](https://github.com/patrickhuber/go-types) for the Option[T any] type. Users of the iter module can utilize Result[T] to capture errors or perform transformations on slices that can contain errors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Async added in v0.2.2

func Async[T any](it Iterator[T], options ...ChannelOption[T]) chan T

Async returns a channel for the given iterator over the context. If the context is canceled, the Async function will return immediately.

func Count

func Count[T any](iterator Iterator[T]) int

func First added in v0.4.0

func First[T any](i Iterator[T]) types.Option[T]

func FirstWhere added in v0.4.0

func FirstWhere[T any](i Iterator[T], condition func(t T) bool) types.Option[T]

func ForEach

func ForEach[T any](iterator Iterator[T], action func(t T))

func ForEachIndex

func ForEachIndex[T any](iterator Iterator[T], action func(i int, t T))

func ToSlice

func ToSlice[T any](iterator Iterator[T]) []T

Types

type ChannelOption

type ChannelOption[T any] func(*channelOption[T])

func WithContext

func WithContext[T any](cx context.Context) ChannelOption[T]

WithContext provides an context.Context for channel operations

type Iterator

type Iterator[T any] interface {
	Next() types.Option[T]
}

Iterator defines a generic iterface for iterating over a sequence

func FromChannel

func FromChannel[T any](ch chan T, options ...ChannelOption[T]) Iterator[T]

func FromMap

func FromMap[TKey comparable, TValue any](m map[TKey]TValue) Iterator[types.Tuple2[TKey, TValue]]

FromMap returns an iterator over the given map. FromMap captures keys of the map in the first call to `Next()`. Subsequent calls to `Next()` track an index into the key slice to return the next key value pair. Each call to `Next()` returns an Option tuple of Key Value pairs.

func FromMapAsync added in v0.2.1

func FromMapAsync[TKey comparable, TValue any](m map[TKey]TValue, cx context.Context) Iterator[types.Tuple2[TKey, TValue]]

FromMapAsync returns a call to FromChannel with a channel created by iterating over the map in a go routine The context passed in is used to pass the WithContext chanel option to the FromChannel call

func FromSlice

func FromSlice[T any](slice []T) Iterator[T]

func New added in v0.5.2

func New[T any](items ...T) Iterator[T]

New creates a new iterator from the list of items

func Range

func Range[T constraints.Integer](begin T, end T) Iterator[T]

func RangeWith added in v0.4.0

func RangeWith[T constraints.Integer](includeBegin bool, begin T, end T, includeEnd bool) Iterator[T]

RangeWith emulates the '[' '(' and ')' ']' syntax used to show a range is inclusive or exclusive

func Repeat added in v0.2.0

func Repeat[T any](element T, count int) Iterator[T]

Repeat returns an iterator that repeats the given `element` `count` times

func Runes added in v0.3.1

func Runes(str string) Iterator[rune]

func Select

func Select[TSource, TTarget any](iterator Iterator[TSource], transform func(TSource) TTarget) Iterator[TTarget]

func Where

func Where[T any](iterator Iterator[T], condition func(t T) bool) Iterator[T]

func Zip added in v0.2.1

func Zip[T1, T2 any](iter1 Iterator[T1], iter2 Iterator[T2]) Iterator[types.Tuple2[T1, T2]]

Zip combines the two iterators into a single iterator of type Tuple[T1, T2]. If the iterators are of different sizes, Zip returns an iterator of the shortest size and consumes the entire longer iterator

type RangeOption added in v0.4.0

type RangeOption int

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL