iter

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2022 License: Apache-2.0, MIT Imports: 2 Imported by: 0

README

iter

Go Report Card Go Reference

Golang generic Iterators, with an intentionally Rust-y flavor.

I have zero expectation that any other party will use this. There are very likely better and more complete alternatives already available - I haven't looked, but if you're reading this I encourage you to run a quick search.

This is a reimplementation the Rust iterator traits I use frequently. These wouldn't be possible in quite the same form prior to the release of generics in Go, which is quite new at the time of writing. Some useful generic slice related functionality can be found in the 'experimental' slices package, though not quite the iterator tools I was missing.

The API as it's currently shaping up isn't quite what I hoped for. The absence of parameterized methods in the language is a bit of a stumbling block. If I come across a better way to deal with it, I'll rewrite accordingly. Nonetheless, there is a fluent api for nearly all operations that do not change the type of the underlying collection (eg Map is not fluent). Manual iteration is comparable to the style found in container/list. An alternative versio following the style of Google's api/iterator is certainly possible, but not currently an objective.

License

SPDX-License-Identifier: MIT or Apache 2.0 license

Documentation

Overview

Package iter provides generic iterators and iterator adapters, with an intentionally Rust-y flavor

Example (Compose)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	doubled := iter.Map[int, int](i, func(n int) int { return n * 2 })
	f := iter.Filter[int](doubled, func(n int) bool { return n > 5 })

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

6
8
Example (Compose_fluent)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	double := func(n int) int { return n * 2 }
	gt5 := func(n int) bool { return n > 5 }

	i := iter.New(list)
	iter.Map[int, int](i, double).
		Filter(gt5).
		ForEach(func(val int) { fmt.Println(val) })
}
Output:

6
8
Example (FilterCount)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	f := iter.Filter[int](i, func(n int) bool { return n%2 == 0 })

	fmt.Println(iter.Count[int](f))
}
Output:

2
Example (FilterCount_fluent)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	c := iter.New(list).
		Filter(func(n int) bool { return n%2 == 0 }).
		Count()

	fmt.Println(c)
}
Output:

2

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func All added in v0.3.0

func All[T any](iter Iterable[T], pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

func Any added in v0.3.0

func Any[T any](iter Iterable[T], pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

func Collect

func Collect[T any](iter Iterable[T]) []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	doubled := iter.Map[int, int](i, func(n int) int { return n * 2 }).
		Filter(func(n int) bool { return n > 5 })

	fmt.Println(iter.Collect[int](doubled))
}
Output:

[6 8]
Example (Fluent)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	doubled := iter.Map[int, int](i, func(n int) int { return n * 2 }).
		Filter(func(n int) bool { return n > 5 }).
		Collect()

	fmt.Println(doubled)
}
Output:

[6 8]

func Count

func Count[T any](iter Iterable[T]) int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5})

	fmt.Println(iter.Count[int](i))
}
Output:

5

func Find added in v0.5.0

func Find[T any](iter Iterable[T], pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func Fold

func Fold[T any, O any](iter Iterable[T], init O, fn func(O, T) O) O

Fold repeatedly applies a reducing operation, reducing the iterator to a single element

Alias for Reduce

func ForEach

func ForEach[T any](iter Iterable[T], fn func(T))

Calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	fn := func(i int) {
		fmt.Println(i)
	}

	i := iter.New(list)
	iter.ForEach[int](i, fn)
}
Output:

1
2
3
4
Example (Fluent)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4
Example (Inline)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	i := iter.New(list)
	iter.ForEach[int](i, func(i int) {
		fmt.Println(i)
	})
}
Output:

1
2
3
4

func Last added in v0.5.0

func Last[T any](iter Iterable[T]) *T

Last Consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

func Max added in v0.4.0

func Max[T is.Ordered](iter Iterable[T]) *T

Max returns the maximum element of an iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{-4, -2, 2, 4})
	fmt.Println(*iter.Max[int](i))

	e := iter.New([]int{})
	fmt.Println(iter.Max[int](e))

	s := iter.New([]string{"abc", "bcd"})
	fmt.Println(*iter.Max[string](s))
}
Output:

4
<nil>
bcd

func Min added in v0.4.0

func Min[T is.Ordered](iter Iterable[T]) *T

Min returns the minimum element of an iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{-4, -2, 2, 4})
	fmt.Println(*iter.Min[int](i))

	e := iter.New([]int{})
	fmt.Println(iter.Min[int](e))

	s := iter.New([]string{"abc", "bcd"})
	fmt.Println(*iter.Min[string](s))
}
Output:

-4
<nil>
abc

func Nth

func Nth[T any](iter Iterable[T], n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	fmt.Println(*iter.Nth[int](i, 0))
	fmt.Println(*iter.Nth[int](i, 0))
	// i only has 2 elements left, so n = 2 is out of range
	fmt.Println(iter.Nth[int](i, 2))
}
Output:

1
2
<nil>
Example (Fluent)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	n := iter.New(list).Nth(2)

	fmt.Println(*n)
}
Output:

3

func Partition

func Partition[T any](iter Iterable[T], pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

func Reduce

func Reduce[T any, O any](iter Iterable[T], init O, fn func(O, T) O) O

Reduce repeatedly applies a reducing operation, reducing the iterator to a single element

Types

type Chained

type Chained[T any] struct {
	// contains filtered or unexported fields
}

Chained is an Iterable that links two Iterables together sequentially.

func Chain

func Chain[T any](a, b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2}
	a2 := []int{3, 4}

	iter := iter.Chain[int](iter.New(a1), iter.New(a2))

	fmt.Println(*iter.Next())
	fmt.Println(*iter.Next())
	fmt.Println(*iter.Next())
	fmt.Println(*iter.Next())
	fmt.Println(iter.Next())
}
Output:

1
2
3
4
<nil>

func (*Chained[T]) All added in v0.3.0

func (iter *Chained[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	t := iter.New(a1).Chain(iter.New(a2)).All(gt0)
	fmt.Println(t)

	i := iter.New(a1).Chain(iter.New(a2))
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Chained[T]) Any added in v0.3.0

func (iter *Chained[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	a1 := []int{1, 2}
	a2 := []int{3, 4}

	t := iter.New(a1).Chain(iter.New(a2)).Any(gt0)
	fmt.Println(t)

	i := iter.New(a1).Chain(iter.New(a2))
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
true
2
3

func (*Chained[T]) Chain

func (iter *Chained[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2}
	a2 := []int{3, 4}
	a3 := []int{5, 6}

	i := iter.New(a1).Chain(iter.New(a2)).Chain(iter.New(a3))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4
5
6

func (*Chained[T]) Collect

func (iter *Chained[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	s := iter.New(a1).Chain(iter.New(a2)).Collect()
	fmt.Println(s)
}
Output:

[1 2 3 4 5 6]

func (*Chained[T]) Count

func (iter *Chained[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2))

	fmt.Println(i.Count())
}
Output:

6

func (*Chained[T]) Filter

func (iter *Chained[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2)).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  i := iter.New(a1).Chain(iter.New(a2)).Filter(isEven)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

2
4
6

func (*Chained[T]) Find

func (iter *Chained[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Chained[T]) ForEach

func (iter *Chained[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	iter.New(a1).Chain(iter.New(a2)).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4
5
6

func (*Chained[T]) Last added in v0.5.0

func (iter *Chained[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2))

	fmt.Println(*i.Last())
}
Output:

6

func (*Chained[T]) Next

func (c *Chained[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Chained[T]) Nth

func (iter *Chained[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2)).Nth(3)

	fmt.Println(*i)
}
Output:

4

func (*Chained[T]) Partition

func (iter *Chained[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{6}
	gt5 := func(a int) bool { return a > 5 }

	a, b := iter.New(a1).Chain(iter.New(a2)).Partition(gt5)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

6
1
2
3

func (*Chained[T]) Skip

func (iter *Chained[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5}

	i := iter.New(a1).Chain(iter.New(a2)).Skip(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4
5

func (*Chained[T]) SkipWhile

func (iter *Chained[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{-1, -2, 3}
	a2 := []int{4, 5}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(a1).Chain(iter.New(a2)).SkipWhile(isNeg)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4
5

func (*Chained[T]) StepBy

func (iter *Chained[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2)).
		StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

2
4
6

func (*Chained[T]) Take

func (iter *Chained[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2)).Take(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2

func (*Chained[T]) TakeWhile

func (iter *Chained[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, -5, -6}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(a1).Chain(iter.New(a2)).TakeWhile(isPos)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4

type Chainer

type Chainer[T any] interface {
	Chain(Iterable[T]) Iterable[T]
}

type Filtered

type Filtered[T any] struct {
	// contains filtered or unexported fields
}

func Filter

func Filter[T any](iter Iterable[T], pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

func (*Filtered[T]) All added in v0.3.0

func (iter *Filtered[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).Filter(gt2).All(gt0)
	fmt.Println(t)

	i := iter.New(list).Filter(gt0)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Filtered[T]) Any added in v0.3.0

func (iter *Filtered[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).Filter(gt2).Any(gt0)
	fmt.Println(t)

	i := iter.New(list).Filter(gt0)
	f := i.Any(gt2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
4

func (*Filtered[T]) Chain

func (iter *Filtered[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Filter(isEven).Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

2
4
5
6

func (*Filtered[T]) Collect

func (iter *Filtered[T]) Collect() []T

Collect transforms an iterator into a slice.

func (*Filtered[T]) Count

func (iter *Filtered[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(i int) bool { return i%2 == 0 }
	i := iter.New([]int{1, 2, 3, 4, 5}).Filter(isEven)

	fmt.Println(i.Count())
}
Output:

2

func (*Filtered[T]) Filter

func (iter *Filtered[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

func (*Filtered[T]) Find

func (iter *Filtered[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Filtered[T]) ForEach

func (iter *Filtered[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{1, 2, 3, 4}

	iter.New(list).Filter(isEven).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

2
4

func (*Filtered[T]) Last added in v0.5.0

func (iter *Filtered[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(i int) bool { return i%2 == 0 }
	i := iter.New([]int{1, 2, 3, 4, 5}).Filter(isEven)

	fmt.Println(*i.Last())
}
Output:

4

func (*Filtered[T]) Next

func (f *Filtered[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Filtered[T]) Nth

func (iter *Filtered[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Filter(isEven).Nth(1)

	fmt.Println(*i)
}
Output:

4

func (*Filtered[T]) Partition

func (iter *Filtered[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	isEven := func(a int) bool { return a%2 == 0 }
	gt5 := func(a int) bool { return a > 5 }

	a, b := iter.New(list).Filter(isEven).Partition(gt5)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

6
2
4

func (*Filtered[T]) Skip

func (iter *Filtered[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Filter(isEven).Skip(1)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

4
<nil>

func (*Filtered[T]) SkipWhile

func (iter *Filtered[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{-1, -2, -3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).Filter(isEven).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

4
<nil>

func (*Filtered[T]) StepBy

func (iter *Filtered[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{1, 2, 3, 4, 5, 6}
	i := iter.New(list).Filter(isEven).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

2
6

func (*Filtered[T]) Take

func (iter *Filtered[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Filter(isEven).Take(1)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-2
<nil>

func (*Filtered[T]) TakeWhile

func (iter *Filtered[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	list := []int{1, 2, 6, -7, -3, -4}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(list).Filter(isEven).TakeWhile(isPos)
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
6
<nil>

type Flat added in v0.5.0

type Flat[I any] struct {
	// contains filtered or unexported fields
}

Flat is an Iterable that flattens one level of nesting in an Iterable of Iteraables

func Flatten added in v0.5.0

func Flatten[I any](it Iterable[Iterable[I]]) *Flat[I]

Flatten creates an iterator that flattens nested structure.

func (*Flat[T]) All added in v0.5.0

func (iter *Flat[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3}),
	})
	t := iter.Flatten[int](data).
		All(gt0)
	fmt.Println(t)
}
Output:

true
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}

	gt0 := func(a int) bool { return a > 0 }
	m1 := iter.Map[[]int](iter.New(data), toIter)
	t := iter.Flatten[int](m1).All(gt0)
	fmt.Println(t)

	gt2 := func(a int) bool { return a > 2 }
	m2 := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m2)
	f := i.All(gt2)
	fmt.Println(f)

	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Flat[T]) Any added in v0.5.0

func (iter *Flat[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3}),
	})
	t := iter.Flatten[int](data).
		Any(gt0)
	fmt.Println(t)
}
Output:

true
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}

	gt0 := func(a int) bool { return a > 0 }
	m1 := iter.Map[[]int](iter.New(data), toIter)
	t := iter.Flatten[int](m1).Any(gt0)
	fmt.Println(t)

	ne2 := func(a int) bool { return a != 2 }
	m2 := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m2)
	f := i.Any(ne2)
	fmt.Println(f)

	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
true
2
3

func (*Flat[T]) Chain added in v0.5.0

func (iter *Flat[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l1 := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3}),
	})
	l2 := iter.New([]iter.Iterable[int]{
		iter.New([]int{4, 5}),
		iter.New([]int{6}),
	})
	a1 := iter.Flatten[int](l1)
	a2 := iter.Flatten[int](l2)

	i := a1.Chain(a2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4
5
6
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	l1 := [][]int{{1, 2}, {3}}
	m1 := iter.Map[[]int](iter.New(l1), toIter)
	a1 := iter.Flatten[int](m1)

	l2 := [][]int{{4, 5}, {6}}
	m2 := iter.Map[[]int](iter.New(l2), toIter)
	a2 := iter.Flatten[int](m2)

	i := a1.Chain(a2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4
5
6

func (*Flat[T]) Collect added in v0.5.0

func (iter *Flat[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data)

	copied := i.Collect()
	fmt.Println(copied)

	// Collected slice should contain copies
	copied[0] = 42
	fmt.Println(copied)
}
Output:

[1 2 3 4]
[42 2 3 4]
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	copied := i.Collect()
	fmt.Println(copied)

	// Collected slice should contain copies
	copied[0] = 42
	fmt.Println(copied)
}
Output:

[1 2 3 4]
[42 2 3 4]

func (*Flat[T]) Count added in v0.5.0

func (iter *Flat[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data)

	fmt.Println(i.Count())
}
Output:

4
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	fmt.Println(i.Count())
}
Output:

4

func (*Flat[T]) Filter added in v0.5.0

func (iter *Flat[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data)

	f := i.Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := i.Filter(gt5)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	f := i.Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := i.Filter(gt5)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4

func (*Flat[T]) Find added in v0.5.0

func (iter *Flat[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	isTwo := func(i int) bool { return i == 2 }
	i := iter.Flatten[int](data)

	fmt.Println(*i.Find(isTwo))
	fmt.Println(i.Find(isTwo))
}
Output:

2
<nil>
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	isTwo := func(i int) bool { return i == 2 }

	fmt.Println(*i.Find(isTwo))
	fmt.Println(i.Find(isTwo))
}
Output:

2
<nil>

func (*Flat[T]) ForEach added in v0.5.0

func (iter *Flat[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})

	iter.Flatten[int](data).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)

	iter.Flatten[int](m).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4

func (*Flat[T]) Last added in v0.5.0

func (iter *Flat[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	fmt.Println(*i.Last())
}
Output:

4

func (*Flat[T]) Next added in v0.5.0

func (f *Flat[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Flat[T]) Nth added in v0.5.0

func (iter *Flat[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, -2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data).
		Nth(1)

	fmt.Println(*i)
}
Output:

-2
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, -2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	fmt.Println(*i.Nth(1))
}
Output:

-2

func (*Flat[T]) Partition added in v0.5.0

func (iter *Flat[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isEven := func(a int) bool { return a%2 == 0 }
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data)

	a, b := i.Partition(isEven)

	fmt.Println(a)
	fmt.Println(b)
}
Output:

[2 4]
[1 3]
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m)

	isEven := func(a int) bool { return a%2 == 0 }
	a, b := i.Partition(isEven)

	fmt.Println(a)
	fmt.Println(b)
}
Output:

[2 4]
[1 3]

func (*Flat[T]) Skip added in v0.5.0

func (iter *Flat[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{-1, -2}),
		iter.New([]int{-3, 4}),
	})
	i := iter.Flatten[int](data).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2
-3
4
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, -2}, {-3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2
-3
4

func (*Flat[T]) SkipWhile added in v0.5.0

func (iter *Flat[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{-1, 2}),
		iter.New([]int{3, 4}),
	})

	i := iter.Flatten[int](data).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
3
4
<nil>
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{-1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)

	isNeg := func(a int) bool { return a < 0 }
	i := iter.Flatten[int](m).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
3
4
<nil>

func (*Flat[T]) StepBy added in v0.5.0

func (iter *Flat[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4, 5, 6}),
	})
	i := iter.Flatten[int](data).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
5
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4, 5, 6}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
5

func (*Flat[T]) Take added in v0.5.0

func (iter *Flat[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{1, 2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data).Take(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{1, 2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)
	i := iter.Flatten[int](m).Take(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1

func (*Flat[T]) TakeWhile added in v0.5.0

func (iter *Flat[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }

	data := iter.New([]iter.Iterable[int]{
		iter.New([]int{-1, -2}),
		iter.New([]int{3, 4}),
	})
	i := iter.Flatten[int](data).TakeWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-1
-2
<nil>
Example (Mapped)
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	toIter := func(a []int) iter.Iterable[int] { return iter.New(a) }
	data := [][]int{{-1, -2}, {3, 4}}
	m := iter.Map[[]int](iter.New(data), toIter)

	isNeg := func(a int) bool { return a < 0 }
	i := iter.Flatten[int](m).TakeWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-1
-2
<nil>

type Iterable

type Iterable[T any] interface {
	// Next advances the iterator and returns the next value.
	//
	// Returns nil when iteration is finished.
	Next() *T
	// Find searches for an element of an iterator that satisfies a predicate.
	//
	// Takes a function that returns true or false. It applies this function to
	// each element of the iterator, and if any of them return true, then Find
	// returns a pointer to the element. If they all return false, it returns
	// nil.
	//
	// Find is short-circuiting; in other words, it will stop processing as soon as
	// the predicate returns true.
	Find(pred func(T) bool) *T
}

type Iterator

type Iterator[T any] struct {
	// contains filtered or unexported fields
}

func New

func New[T any](slice []T) *Iterator[T]

New creates a new lazy iterator over the provided slice

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	slice := []int{1, 2, 3}
	i := iter.New(slice)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

1
2
3
<nil>

func (*Iterator[T]) All added in v0.3.0

func (iter *Iterator[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3}

	t := iter.New(list).All(gt0)
	fmt.Println(t)

	i := iter.New(list)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Iterator[T]) Any added in v0.3.0

func (iter *Iterator[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	list := []int{1, 2, 3}

	t := iter.New(list).Any(gt0)
	fmt.Println(t)

	i := iter.New(list)
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
true
2
3

func (*Iterator[T]) Chain

func (iter *Iterator[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4
5
6

func (*Iterator[T]) Collect

func (iter *Iterator[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	copied := i.Collect()
	fmt.Println(copied)

	// Collected slice should contain copies
	copied[0] = 42
	fmt.Println(list)
	fmt.Println(copied)
}
Output:

[1 2 3 4]
[1 2 3 4]
[42 2 3 4]

func (*Iterator[T]) Count

func (iter *Iterator[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5})

	fmt.Println(i.Count())
}
Output:

5

func (*Iterator[T]) Filter

func (iter *Iterator[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4})

	f := i.Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := i.Filter(gt5)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4

func (*Iterator[T]) Find

func (iter *Iterator[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	isTwo := func(i int) bool { return i == 2 }
	i := iter.New(list)

	fmt.Println(*i.Find(isTwo))
	fmt.Println(i.Find(isTwo))
}
Output:

2
<nil>

func (*Iterator[T]) ForEach

func (iter *Iterator[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4

func (*Iterator[T]) Last added in v0.5.0

func (iter *Iterator[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5})

	fmt.Println(*i.Last())
}
Output:

5

func (*Iterator[T]) Next

func (iter *Iterator[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Iterator[T]) Nth

func (iter *Iterator[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}
	i := iter.New(list).Nth(1)

	fmt.Println(*i)
}
Output:

-2

func (*Iterator[T]) Partition

func (iter *Iterator[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	isEven := func(a int) bool { return a%2 == 0 }

	a, b := iter.New(list).Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

2
4
1
3

func (*Iterator[T]) Rev

func (iter *Iterator[T]) Rev() *RevIterator[T]

Rev reverses the iteration order of this iterator

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	slice := []int{1, 2, 3}
	i := iter.New(slice).Rev()

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

3
2
1
<nil>

func (*Iterator[T]) Skip

func (iter *Iterator[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2
-3
4

func (*Iterator[T]) SkipWhile

func (iter *Iterator[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
3
4
<nil>

func (*Iterator[T]) StepBy

func (iter *Iterator[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	i := iter.New(list).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
5

func (*Iterator[T]) Take

func (iter *Iterator[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}
	i := iter.New(list).Take(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-1

func (*Iterator[T]) TakeWhile

func (iter *Iterator[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).TakeWhile(isNeg)
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-1
-2
<nil>

type ListIterator added in v0.4.0

type ListIterator[T any] struct {
	// contains filtered or unexported fields
}

ListIterator is a lazy iterator over a container/list

func FromList added in v0.4.0

func FromList[T any](list *list.List) *ListIterator[T]

New creates a new lazy iterator over the provided container/list

func (*ListIterator[T]) All added in v0.4.0

func (iter *ListIterator[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }

	t := iter.FromList[int](l).All(gt0)
	fmt.Println(t)

	i := iter.FromList[int](l)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*ListIterator[T]) Any added in v0.4.0

func (iter *ListIterator[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }

	t := iter.FromList[int](l).Any(gt0)
	fmt.Println(t)

	i := iter.FromList[int](l)
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
true
2
3

func (*ListIterator[T]) Chain added in v0.4.0

func (iter *ListIterator[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l1, l2 := list.New(), list.New()
	// fill linked lists
	for i := 1; i <= 2; i++ {
		l1.PushBack(i)
	}
	for i := 3; i <= 4; i++ {
		l1.PushBack(i)
	}

	i := iter.FromList[int](l1).Chain(iter.FromList[int](l2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4

func (*ListIterator[T]) Collect added in v0.4.0

func (iter *ListIterator[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	copied := i.Collect()
	fmt.Println(copied)

	// Collected slice should contain copies
	copied[0] = 42
	fmt.Println(l.Front().Value)
	fmt.Println(copied)
}
Output:

[1 2 3 4]
1
[42 2 3 4]

func (*ListIterator[T]) Count added in v0.4.0

func (iter *ListIterator[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	fmt.Println(i.Count())
}
Output:

4

func (*ListIterator[T]) Filter added in v0.4.0

func (iter *ListIterator[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	f := i.Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := i.Filter(gt2)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4

func (*ListIterator[T]) Find added in v0.4.0

func (iter *ListIterator[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isTwo := func(i int) bool { return i == 2 }
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	fmt.Println(*i.Find(isTwo))
	fmt.Println(i.Find(isTwo))
}
Output:

2
<nil>

func (*ListIterator[T]) ForEach added in v0.4.0

func (iter *ListIterator[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	iter.FromList[int](l).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4

func (*ListIterator[T]) Last added in v0.5.0

func (iter *ListIterator[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	fmt.Println(*i.Last())
}
Output:

4

func (*ListIterator[T]) Next added in v0.4.0

func (it *ListIterator[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished, or if the next value does not conform to the specified type.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

1
2
3
4
<nil>

func (*ListIterator[T]) Nth added in v0.4.0

func (iter *ListIterator[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l).Nth(1)

	fmt.Println(*i)
}
Output:

2

func (*ListIterator[T]) Partition added in v0.4.0

func (iter *ListIterator[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	isEven := func(a int) bool { return a%2 == 0 }

	a, b := iter.FromList[int](l).Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

2
4
1
3

func (*ListIterator[T]) Skip added in v0.4.0

func (iter *ListIterator[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

2
3
4

func (*ListIterator[T]) SkipWhile added in v0.4.0

func (iter *ListIterator[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with -1 to 2
	for i := -1; i <= 2; i++ {
		l.PushBack(i)
	}

	isNeg := func(a int) bool { return a < 0 }

	i := iter.FromList[int](l).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

0
1
2
<nil>

func (*ListIterator[T]) StepBy added in v0.4.0

func (iter *ListIterator[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 6
	for i := 1; i <= 6; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
5

func (*ListIterator[T]) Take added in v0.4.0

func (iter *ListIterator[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := 1; i <= 4; i++ {
		l.PushBack(i)
	}

	i := iter.FromList[int](l).Take(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1

func (*ListIterator[T]) TakeWhile added in v0.4.0

func (iter *ListIterator[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"container/list"
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	l := list.New()
	// fill linked list with 1 to 4
	for i := -1; i <= 1; i++ {
		l.PushBack(i)
	}

	isNeg := func(a int) bool { return a < 0 }

	i := iter.FromList[int](l).TakeWhile(isNeg)
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-1
<nil>

type Mapped

type Mapped[T any, O any] struct {
	// contains filtered or unexported fields
}

func Map

func Map[T any, O any](iter Iterable[T], fn func(T) O) *Mapped[T, O]

Map returns an iterator that applies a function to every element.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	i := iter.New(list)

	doubled := iter.Map[int, int](i, func(n int) int { return n * 2 })

	for val := doubled.Next(); val != nil; val = doubled.Next() {
		fmt.Println(*val)
	}
}
Output:

2
4
6
8

func (*Mapped[T, O]) All added in v0.3.0

func (iter *Mapped[T, O]) All(pred func(O) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	ident := func(i int) int { return i }
	list := []int{1, 2, 3}

	i := iter.New(list)
	t := iter.Map[int, int](i, ident).All(gt0)
	fmt.Println(t)

	i = iter.New(list)
	m := iter.Map[int, int](i, ident)
	f := m.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Mapped[T, O]) Any added in v0.3.0

func (iter *Mapped[T, O]) Any(pred func(O) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	ident := func(i int) int { return i }
	list := []int{1, 2, 3}

	i := iter.New(list)
	t := iter.Map[int, int](i, ident).Any(gt0)
	fmt.Println(t)

	i = iter.New(list)
	m := iter.Map[int, int](i, ident)
	f := m.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
2

func (*Mapped[T, O]) Chain

func (iter *Mapped[T, O]) Chain(b Iterable[O]) *Chained[O]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }

	a1 := iter.New([]int{1, 2, 3})
	a2 := iter.New([]int{4, 5, 6})

	i := iter.Map[int, int](a1, ident).Chain(a2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
3
4
5
6

func (*Mapped[T, O]) Collect

func (iter *Mapped[T, O]) Collect() []O

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }
	i := iter.New([]int{1, 2, 3})

	s := iter.Map[int](i, ident).Collect()
	fmt.Println(s)
}
Output:

[1 2 3]

func (*Mapped[T, O]) Count

func (iter *Mapped[T, O]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }
	i := iter.New([]int{1, 2, 3, 4, 5})

	fmt.Println(iter.Map[int, int](i, ident).Count())
}
Output:

5

func (*Mapped[T, O]) Filter

func (iter *Mapped[T, O]) Filter(pred func(O) bool) *Filtered[O]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }
	i := iter.New([]int{1, 2, 3, 4})

	f := iter.Map[int, int](i, ident).Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := iter.Map(i, ident).Filter(gt5)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4

func (*Mapped[T, O]) Find

func (iter *Mapped[T, O]) Find(pred func(O) bool) *O

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Mapped[T, O]) ForEach

func (iter *Mapped[T, O]) ForEach(fn func(O))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	ident := func(i int) int { return i }

	i := iter.New(list)
	iter.Map[int, int](i, ident).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3
4

func (*Mapped[T, O]) Last added in v0.5.0

func (iter *Mapped[T, O]) Last() *O

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }
	i := iter.New([]int{1, 2, 3, 4, 5})
	m := *iter.Map[int, int](i, ident)

	fmt.Println(*m.Last())
}
Output:

5

func (*Mapped[T, O]) Next

func (m *Mapped[T, O]) Next() *O

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Mapped[T, O]) Nth

func (iter *Mapped[T, O]) Nth(n int) *O

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	ident := func(i int) int { return i }

	i := iter.New(list)
	m := iter.Map[int, int](i, ident).Nth(2)

	fmt.Println(*m)
}
Output:

3

func (*Mapped[T, O]) Partition

func (iter *Mapped[T, O]) Partition(pred func(O) bool) ([]O, []O)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	isEven := func(a int) bool { return a%2 == 0 }
	ident := func(i int) int { return i }

	i := iter.New(list)
	a, b := iter.Map[int, int](i, ident).Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

2
4
1
3

func (*Mapped[T, O]) Skip

func (iter *Mapped[T, O]) Skip(n int) *Skipped[O]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, 3, 4}
	ident := func(i int) int { return i }

	i := iter.Map[int, int](iter.New(list), ident).Skip(2)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

3
4
<nil>

func (*Mapped[T, O]) SkipWhile

func (iter *Mapped[T, O]) SkipWhile(pred func(O) bool) *SkipWhileT[O]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }
	ident := func(i int) int { return i }

	i := iter.Map[int, int](iter.New(list), ident).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
3
4
<nil>

func (*Mapped[T, O]) StepBy

func (iter *Mapped[T, O]) StepBy(step int) *Stepped[O]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	ident := func(i int) int { return i }
	list := []int{1, 2, 3, 4, 5, 6}

	i := iter.New(list)
	m := iter.Map[int, int](i, ident).StepBy(2)

	for val := m.Next(); val != nil; val = m.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
5

func (*Mapped[T, O]) Take

func (iter *Mapped[T, O]) Take(n int) *Taken[O]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	ident := func(i int) int { return i }

	i := iter.New(list)
	m := iter.Map[int, int](i, ident).Take(2)

	fmt.Println(*m.Next())
	fmt.Println(*m.Next())
	fmt.Println(m.Next())
}
Output:

-1
-2
<nil>

func (*Mapped[T, O]) TakeWhile

func (iter *Mapped[T, O]) TakeWhile(pred func(O) bool) *TakeWhileT[O]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	ident := func(i int) int { return i }
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list)
	m := iter.Map[int, int](i, ident).TakeWhile(isNeg)

	fmt.Println(*m.Next())
	fmt.Println(*m.Next())
	fmt.Println(m.Next())
}
Output:

-1
-2
<nil>

type RevIterator

type RevIterator[T any] struct {
	// contains filtered or unexported fields
}

An Iterable with the direction reversed.

func (*RevIterator[T]) All added in v0.3.0

func (iter *RevIterator[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3}

	t := iter.New(list).Rev().All(gt0)
	fmt.Println(t)

	i := iter.New(list).Rev()
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
false
1

func (*RevIterator[T]) Any added in v0.3.0

func (iter *RevIterator[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3}

	t := iter.New(list).Rev().Any(gt0)
	fmt.Println(t)

	i := iter.New(list).Rev()
	f := i.Any(gt2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
2

func (*RevIterator[T]) Chain

func (iter *RevIterator[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Rev().Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
2
1
4
5
6

func (*RevIterator[T]) Collect

func (iter *RevIterator[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3}

	s := iter.New(list).Rev().Collect()
	fmt.Println(s)
}
Output:

[3 2 1]

func (*RevIterator[T]) Count

func (iter *RevIterator[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Rev()

	fmt.Println(i.Count())
}
Output:

5

func (*RevIterator[T]) Filter

func (iter *RevIterator[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	f := iter.New(list).
		Rev().
		Filter(func(n int) bool { return n > 2 })

	// alternatively,
	//  gt2 := func(n int) bool { return n > 2 }
	//  f := iter.New(list).Rev().Filter(gt5)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

4
3

func (*RevIterator[T]) Find

func (iter *RevIterator[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*RevIterator[T]) ForEach

func (iter *RevIterator[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).Rev().
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

4
3
2
1

func (*RevIterator[T]) Last added in v0.5.0

func (iter *RevIterator[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Rev()

	fmt.Println(*i.Last())
}
Output:

1

func (*RevIterator[T]) Next

func (iter *RevIterator[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*RevIterator[T]) Nth

func (iter *RevIterator[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}
	i := iter.New(list).Rev().Nth(1)

	fmt.Println(*i)
}
Output:

-3

func (*RevIterator[T]) Partition

func (iter *RevIterator[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	isEven := func(a int) bool { return a%2 == 0 }

	a, b := iter.New(list).Rev().Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

4
2
3
1

func (*RevIterator[T]) Skip

func (iter *RevIterator[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Rev().Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-3
-2
-1

func (*RevIterator[T]) SkipWhile

func (iter *RevIterator[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).Rev().SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

4
3
2
-1
<nil>

func (*RevIterator[T]) StepBy

func (iter *RevIterator[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	i := iter.New(list).Rev().StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

6
4
2

func (*RevIterator[T]) Take

func (iter *RevIterator[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}
	i := iter.New(list).Rev().Take(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

4

func (*RevIterator[T]) TakeWhile

func (iter *RevIterator[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(list).Rev().TakeWhile(isPos)
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

4
3
<nil>

type SkipWhileT

type SkipWhileT[T any] struct {
	// contains filtered or unexported fields
}

SkipWhile is an Iterable that rejects elements while predicate returns true.

func SkipWhile

func SkipWhile[T any](iter Iterable[T], pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }

	iter := iter.SkipWhile[int](iter.New(list), isNeg)

	for val := iter.Next(); val != nil; val = iter.Next() {
		fmt.Println(*val)
	}
	fmt.Println(iter.Next())
}
Output:

3
4
<nil>

func (*SkipWhileT[T]) All added in v0.4.0

func (iter *SkipWhileT[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	ne2 := func(a int) bool { return a != 2 }
	t := iter.New(list).SkipWhile(isNeg).All(ne2)
	fmt.Println(t)

	gt5 := func(a int) bool { return a > 5 }
	i := iter.New(list).SkipWhile(isNeg)
	f := i.All(gt5)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
false
4

func (*SkipWhileT[T]) Any added in v0.4.0

func (iter *SkipWhileT[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	ne2 := func(a int) bool { return a != 2 }
	t := iter.New(list).SkipWhile(isNeg).Any(ne2)
	fmt.Println(t)

	gt0 := func(a int) bool { return a > 0 }
	i := iter.New(list).SkipWhile(isNeg)
	f := i.Any(gt0)
	fmt.Println(f)

	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
4

func (*SkipWhileT[T]) Chain added in v0.4.0

func (iter *SkipWhileT[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	a := iter.New(list).SkipWhile(isNeg)
	b := iter.New([]int{5, 6})

	i := a.Chain(b)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4
5
6

func (*SkipWhileT[T]) Collect added in v0.4.0

func (iter *SkipWhileT[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	s := iter.New(list).SkipWhile(isNeg).Collect()

	fmt.Println(s)
}
Output:

[3 4]

func (*SkipWhileT[T]) Count added in v0.4.0

func (iter *SkipWhileT[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg)

	fmt.Println(i.Count())
}
Output:

2

func (*SkipWhileT[T]) Filter added in v0.4.0

func (iter *SkipWhileT[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	i := iter.New(list).SkipWhile(isNeg).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  i := iter.New(list).SkipWhile(isNeg).Filter(isEven)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

4

func (*SkipWhileT[T]) Find

func (iter *SkipWhileT[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*SkipWhileT[T]) ForEach added in v0.4.0

func (iter *SkipWhileT[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	iter.New(list).SkipWhile(isNeg).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

3
4

func (*SkipWhileT[T]) Last added in v0.5.0

func (iter *SkipWhileT[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg)

	fmt.Println(*i.Last())
}
Output:

4

func (*SkipWhileT[T]) Next

func (s *SkipWhileT[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*SkipWhileT[T]) Nth added in v0.4.0

func (iter *SkipWhileT[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).Nth(1)

	fmt.Println(*i)
}
Output:

4

func (*SkipWhileT[T]) Partition added in v0.4.0

func (iter *SkipWhileT[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }

	list := []int{-1, -2, 3, 4}
	a, b := iter.New(list).SkipWhile(isNeg).Partition(isOdd)

	fmt.Println(a)
	fmt.Println(b)
}
Output:

[3]
[4]

func (*SkipWhileT[T]) Skip added in v0.4.0

func (iter *SkipWhileT[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

4

func (*SkipWhileT[T]) SkipWhile added in v0.4.0

func (iter *SkipWhileT[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).SkipWhile(isOdd)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

4

func (*SkipWhileT[T]) StepBy added in v0.4.0

func (iter *SkipWhileT[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3

func (*SkipWhileT[T]) Take added in v0.4.0

func (iter *SkipWhileT[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).Take(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4

func (*SkipWhileT[T]) TakeWhile added in v0.4.0

func (iter *SkipWhileT[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).SkipWhile(isNeg).TakeWhile(isOdd)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3

type Skipped

type Skipped[T any] struct {
	// contains filtered or unexported fields
}

Skipped is an iterator that skips over n elements.

func Skip

func Skip[T any](iter Iterable[T], n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

func (*Skipped[T]) All added in v0.3.0

func (iter *Skipped[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3}

	t := iter.New(list).Skip(1).All(gt0)
	fmt.Println(t)

	i := iter.New(list).Skip(1)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
false
3

func (*Skipped[T]) Any added in v0.3.0

func (iter *Skipped[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).Skip(1).Any(gt0)
	fmt.Println(t)

	i := iter.New(list).Skip(1)
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
4

func (*Skipped[T]) Chain

func (iter *Skipped[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Skip(2).Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
4
5
6

func (*Skipped[T]) Collect

func (iter *Skipped[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	s := iter.New(list).Skip(1).Collect()
	fmt.Println(s)
}
Output:

[2 3 4]

func (*Skipped[T]) Count

func (iter *Skipped[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Skip(3)

	fmt.Println(i.Count())
}
Output:

2

func (*Skipped[T]) Filter

func (iter *Skipped[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	f := iter.New(list).Skip(2).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  f := iter.New(list).Skip(2).Filter(isEven)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

4

func (*Skipped[T]) Find

func (iter *Skipped[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Skipped[T]) ForEach

func (iter *Skipped[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).Skip(2).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

3
4

func (*Skipped[T]) Last added in v0.5.0

func (iter *Skipped[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Skip(3)

	fmt.Println(*i.Last())
}
Output:

5

func (*Skipped[T]) Next

func (s *Skipped[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Skipped[T]) Nth

func (iter *Skipped[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Skip(2).Nth(1)

	fmt.Println(*i)
}
Output:

4

func (*Skipped[T]) Partition

func (iter *Skipped[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	isEven := func(a int) bool { return a%2 == 0 }

	a, b := iter.New(list).Skip(2).Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

4
6
3
5

func (*Skipped[T]) Skip added in v0.4.0

func (iter *Skipped[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

func (*Skipped[T]) SkipWhile

func (iter *Skipped[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, -3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).Skip(2).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

4
<nil>

func (*Skipped[T]) StepBy

func (iter *Skipped[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	i := iter.New(list).Skip(2).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

3
5

func (*Skipped[T]) Take

func (iter *Skipped[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Skip(2).Take(1)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-3
<nil>

func (*Skipped[T]) TakeWhile

func (iter *Skipped[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 6, 7, -3, 4}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(list).Skip(2).TakeWhile(isPos)
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

6
7
<nil>

type Stepped

type Stepped[T any] struct {
	// contains filtered or unexported fields
}

Stepped is an Iterable for stepping iterators by a custom amount.

func StepBy

func StepBy[T any](a Iterable[T], step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

func (*Stepped[T]) All added in v0.3.0

func (iter *Stepped[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).StepBy(2).All(gt0)
	fmt.Println(t)

	i := iter.New(list).StepBy(2)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
false
3

func (*Stepped[T]) Any added in v0.3.0

func (iter *Stepped[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).StepBy(2).Any(gt0)
	fmt.Println(t)

	i := iter.New(list).StepBy(2)
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
3

func (*Stepped[T]) Chain

func (iter *Stepped[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).StepBy(2).Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
3
4
5
6

func (*Stepped[T]) Collect

func (iter *Stepped[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3}
	s := iter.New(list).StepBy(2).Collect()
	fmt.Println(s)
}
Output:

[1 3]

func (*Stepped[T]) Count

func (iter *Stepped[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).StepBy(2)

	fmt.Println(i.Count())
}
Output:

3

func (*Stepped[T]) Filter

func (iter *Stepped[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{2, 3, 4, 5, 6}
	f := iter.New(list).StepBy(2).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  f := iter.New(list).StepBy(2).Filter(isEven)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

2
4
6

func (*Stepped[T]) Find

func (iter *Stepped[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Stepped[T]) ForEach

func (iter *Stepped[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).StepBy(2).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
3

func (*Stepped[T]) Last added in v0.5.0

func (iter *Stepped[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).StepBy(2)

	fmt.Println(*i.Last())
}
Output:

5

func (*Stepped[T]) Next

func (s *Stepped[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Stepped[T]) Nth

func (iter *Stepped[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).StepBy(2).Nth(1)

	fmt.Println(*i)
}
Output:

-3

func (*Stepped[T]) Partition

func (iter *Stepped[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	gte5 := func(a int) bool { return a >= 5 }

	a, b := iter.New(list).StepBy(2).Partition(gte5)

	fmt.Println(a)
	fmt.Println(b)
}
Output:

[5]
[1 3]

func (*Stepped[T]) Skip

func (iter *Stepped[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).StepBy(2).Skip(1)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-3
<nil>

func (*Stepped[T]) SkipWhile

func (iter *Stepped[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4, 5}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).StepBy(2).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

5
<nil>

func (*Stepped[T]) StepBy added in v0.4.0

func (iter *Stepped[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

func (*Stepped[T]) Take

func (iter *Stepped[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).StepBy(2).Take(1)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-1
<nil>

func (*Stepped[T]) TakeWhile

func (iter *Stepped[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 6, -7, -3, -4}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(list).StepBy(2).TakeWhile(isPos)
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

1
6
<nil>

type TakeWhileT

type TakeWhileT[T any] struct {
	// contains filtered or unexported fields
}

TakeWhile is an Iterable that only yields elements while a predicate returns true.

func TakeWhile

func TakeWhile[T any](iter Iterable[T], pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

TakeWhile takes a predicate function as an argument. It will call this function on each element of the iterator, and yield elements while it returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, 3, 4}
	isNeg := func(a int) bool { return a < 0 }

	iter := iter.TakeWhile[int](iter.New(list), isNeg)

	for val := iter.Next(); val != nil; val = iter.Next() {
		fmt.Println(*val)
	}
	fmt.Println(iter.Next())
}
Output:

-1
-2
<nil>

func (*TakeWhileT[T]) All added in v0.4.0

func (iter *TakeWhileT[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	ne2 := func(a int) bool { return a != 2 }
	t := iter.New(list).TakeWhile(isNeg).All(ne2)
	fmt.Println(t)

	gt2 := func(a int) bool { return a > 2 }
	i := iter.New(list).TakeWhile(isNeg)
	f := i.All(gt2)
	fmt.Println(f)

	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
false
-2

func (*TakeWhileT[T]) Any added in v0.4.0

func (iter *TakeWhileT[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	isOdd := func(a int) bool { return a%2 != 0 }
	t := iter.New(list).TakeWhile(isNeg).Any(isOdd)
	fmt.Println(t)

	ne2 := func(a int) bool { return a != 2 }
	i := iter.New(list).TakeWhile(isNeg)
	f := i.Any(ne2)
	fmt.Println(f)

	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
}
Output:

true
true
-2

func (*TakeWhileT[T]) Chain added in v0.4.0

func (iter *TakeWhileT[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	a := iter.New(list).TakeWhile(isNeg)
	b := iter.New([]int{5, 6})

	i := a.Chain(b)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-1
-2
5
6

func (*TakeWhileT[T]) Collect added in v0.4.0

func (iter *TakeWhileT[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	s := iter.New(list).TakeWhile(isNeg).Collect()

	fmt.Println(s)
}
Output:

[-1 -2]

func (*TakeWhileT[T]) Count added in v0.4.0

func (iter *TakeWhileT[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg)

	fmt.Println(i.Count())
}
Output:

2

func (*TakeWhileT[T]) Filter added in v0.4.0

func (iter *TakeWhileT[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	i := iter.New(list).TakeWhile(isNeg).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  i := iter.New(a1).Chain(iter.New(a2)).Filter(isEven)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2

func (*TakeWhileT[T]) Find

func (iter *TakeWhileT[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*TakeWhileT[T]) ForEach added in v0.4.0

func (iter *TakeWhileT[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}

	iter.New(list).TakeWhile(isNeg).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

-1
-2

func (*TakeWhileT[T]) Last added in v0.5.0

func (iter *TakeWhileT[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg)

	fmt.Println(*i.Last())
}
Output:

-2

func (*TakeWhileT[T]) Next

func (s *TakeWhileT[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*TakeWhileT[T]) Nth added in v0.4.0

func (iter *TakeWhileT[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).Nth(1)

	fmt.Println(*i)
}
Output:

-2

func (*TakeWhileT[T]) Partition added in v0.4.0

func (iter *TakeWhileT[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }

	list := []int{-1, -2, 3, 4}
	a, b := iter.New(list).TakeWhile(isNeg).Partition(isOdd)

	fmt.Println(a)
	fmt.Println(b)
}
Output:

[-1]
[-2]

func (*TakeWhileT[T]) Skip added in v0.4.0

func (iter *TakeWhileT[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).Skip(1)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2

func (*TakeWhileT[T]) SkipWhile added in v0.4.0

func (iter *TakeWhileT[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).SkipWhile(isOdd)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-2

func (*TakeWhileT[T]) StepBy added in v0.4.0

func (iter *TakeWhileT[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-1

func (*TakeWhileT[T]) Take added in v0.4.0

func (iter *TakeWhileT[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).Take(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-1
-2

func (*TakeWhileT[T]) TakeWhile added in v0.4.0

func (iter *TakeWhileT[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	isNeg := func(a int) bool { return a < 0 }
	isOdd := func(a int) bool { return a%2 != 0 }
	list := []int{-1, -2, 3, 4}
	i := iter.New(list).TakeWhile(isNeg).TakeWhile(isOdd)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

-1

type Taken

type Taken[T any] struct {
	// contains filtered or unexported fields
}

Taken is an iterator that only iterates over the first n elements.

func Take

func Take[T any](iter Iterable[T], n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

func (*Taken[T]) All added in v0.3.0

func (iter *Taken[T]) All(pred func(T) bool) bool

All tests if every element of the iterator matches a predicate.

All takes a function that returns true or false. It applies this function to each element of the iterator, and if they all return true, then so does All. If any of them return false, it returns false.

All is short-circuiting; in other words, it will stop processing as soon as it finds a false, given that no matter what else happens, the result will also be false.

An empty iterator returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	gt2 := func(a int) bool { return a > 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).Take(3).All(gt0)
	fmt.Println(t)

	i := iter.New(list).Take(3)
	f := i.All(gt2)
	fmt.Println(f)
	// All stops at the first false, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
false
2
3

func (*Taken[T]) Any added in v0.3.0

func (iter *Taken[T]) Any(pred func(T) bool) bool

Any tests if any element of the iterator matches a predicate.

Any takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then so does Any. If they all return false, it returns false.

Any is short-circuiting; in other words, it will stop processing as soon as it finds a true, given that no matter what else happens, the result will also be true.

An empty iterator returns false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	gt0 := func(a int) bool { return a > 0 }
	ne2 := func(a int) bool { return a != 2 }
	list := []int{1, 2, 3, 4}

	t := iter.New(list).Take(3).Any(gt0)
	fmt.Println(t)

	i := iter.New(list).Take(3)
	f := i.Any(ne2)
	fmt.Println(f)
	// Any stops at the first true, so there are still more elements
	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
}
Output:

true
true
2
3

func (*Taken[T]) Chain

func (iter *Taken[T]) Chain(b Iterable[T]) *Chained[T]

Chain takes two iterators and creates a new iterator over both in sequence.

Chain will return a new iterator which will first iterate over values from the first iterator and then over values from the second iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	a1 := []int{1, 2, 3}
	a2 := []int{4, 5, 6}

	i := iter.New(a1).Take(2).Chain(iter.New(a2))

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1
2
4
5
6

func (*Taken[T]) Collect

func (iter *Taken[T]) Collect() []T

Collect transforms an iterator into a slice.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3}
	s := iter.New(list).Take(2).Collect()
	fmt.Println(s)
}
Output:

[1 2]

func (*Taken[T]) Count

func (iter *Taken[T]) Count() int

Count consumes the iterator, counting the number of iterations and returning it.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Take(3)

	fmt.Println(i.Count())
}
Output:

3

func (*Taken[T]) Filter

func (iter *Taken[T]) Filter(pred func(T) bool) *Filtered[T]

Filter returns an iterator which uses a predicate function to determine if an element should be yielded.

The returned iterator will yield only the elements for which the predicate returns true.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}
	f := iter.New(list).Take(2).
		Filter(func(n int) bool { return n%2 == 0 })

	// alternatively,
	//  isEven := func(n int) bool { return n%2 == 0 }
	//  f := iter.New(list).Take(2).Filter(isEven)

	for val := f.Next(); val != nil; val = f.Next() {
		fmt.Println(*val)
	}
}
Output:

2

func (*Taken[T]) Find

func (iter *Taken[T]) Find(pred func(T) bool) *T

Find searches for an element of an iterator that satisfies a predicate.

Takes a function that returns true or false. It applies this function to each element of the iterator, and if any of them return true, then Find returns a pointer to the element. If they all return false, it returns nil.

Find is short-circuiting; in other words, it will stop processing as soon as the predicate returns true.

func (*Taken[T]) ForEach

func (iter *Taken[T]) ForEach(fn func(T))

ForEach calls a function on each element of an iterator.

This is equivalent to using a for loop on the iterator, although break and continue are not possible.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4}

	iter.New(list).Take(3).
		ForEach(func(i int) { fmt.Println(i) })
}
Output:

1
2
3

func (*Taken[T]) Last added in v0.5.0

func (iter *Taken[T]) Last() *T

Last consumes the iterator, returning the last element.

This method will evaluate the iterator until it returns nil. While doing so, it keeps track of the current element. After nil is returned, Last will then return the last element it saw.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	i := iter.New([]int{1, 2, 3, 4, 5}).Take(3)

	fmt.Println(*i.Last())
}
Output:

3

func (*Taken[T]) Next

func (s *Taken[T]) Next() *T

Next advances the iterator and returns the next value.

Returns nil when iteration is finished.

func (*Taken[T]) Nth

func (iter *Taken[T]) Nth(n int) *T

Nth returns the nth element of the iterator.

Like most indexing operations, the count starts from zero, so Nth(0) returns the first value, nth(1) the second, and so on.

Note that all preceding elements, as well as the returned element, will be consumed from the iterator. That means that the preceding elements will be discarded, and also that calling Nth(0) multiple times on the same iterator will return different elements.

Nth will return nil if n is greater than or equal to the length of the iterator.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Take(3).Nth(1)

	fmt.Println(*i)
}
Output:

-2

func (*Taken[T]) Partition

func (iter *Taken[T]) Partition(pred func(T) bool) ([]T, []T)

Partition consumes an iterator, creating two slices from it.

The first slice contains all of the elements for which the predicate returned true, and the second slice contains all of the elements for which it returned false.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	isEven := func(a int) bool { return a%2 == 0 }

	a, b := iter.New(list).Take(2).Partition(isEven)

	for _, v := range a {
		fmt.Println(v)
	}
	for _, v := range b {
		fmt.Println(v)
	}
}
Output:

2
1

func (*Taken[T]) Skip

func (iter *Taken[T]) Skip(n int) *Skipped[T]

Skip creates an iterator that skips the first n elements.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, -2, -3, 4}

	i := iter.New(list).Take(3).Skip(1)

	fmt.Println(*i.Next())
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

-2
-3
<nil>

func (*Taken[T]) SkipWhile

func (iter *Taken[T]) SkipWhile(pred func(T) bool) *SkipWhileT[T]

SkipWhile creates an iterator that skips elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{-1, 2, -3, 4}
	isNeg := func(a int) bool { return a < 0 }

	i := iter.New(list).Take(2).SkipWhile(isNeg)

	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

2
<nil>

func (*Taken[T]) StepBy

func (iter *Taken[T]) StepBy(step int) *Stepped[T]

StepBy creates an iterator starting at the same point, but stepping by the given amount at each iteration.

The method will panic if the given step is <= 0.

Note 1: The first element of the iterator will always be returned, regardless of the step given.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, 2, 3, 4, 5, 6}
	i := iter.New(list).Take(2).StepBy(2)

	for val := i.Next(); val != nil; val = i.Next() {
		fmt.Println(*val)
	}
}
Output:

1

func (*Taken[T]) Take added in v0.4.0

func (iter *Taken[T]) Take(n int) *Taken[T]

Take creates an iterator that yields the first n elements, or fewer if the underlying iterator ends sooner.

func (*Taken[T]) TakeWhile

func (iter *Taken[T]) TakeWhile(pred func(T) bool) *TakeWhileT[T]

TakeWhile Creates an iterator that yields elements based on a predicate.

Example
package main

import (
	"fmt"

	"github.com/partylich/go/iter"
)

func main() {
	list := []int{1, -2, 6, 7, -3, 4}
	isPos := func(a int) bool { return a > 0 }

	i := iter.New(list).Take(2).TakeWhile(isPos)
	fmt.Println(*i.Next())
	fmt.Println(i.Next())
}
Output:

1
<nil>

Directories

Path Synopsis
cmd
gen

Jump to

Keyboard shortcuts

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