iterator

package
v0.15.3 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2024 License: MIT Imports: 0 Imported by: 4

Documentation

Overview

Package iterator allows iterating over sequences of values, for example the contents of a container.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Collect

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

Collect advances iter to the end and returns all of the items seen as a slice.

func Equal

func Equal[T comparable](iters ...Iterator[T]) bool

Equal returns true if the given iterators yield the same items in the same order. Consumes the iterators.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	fmt.Println(
		iterator.Equal(
			iterator.Slice([]string{"a", "b", "c"}),
			iterator.Slice([]string{"a", "b", "c"}),
		),
	)

	fmt.Println(
		iterator.Equal(
			iterator.Slice([]string{"a", "b", "c"}),
			iterator.Slice([]string{"a", "b", "c", "d"}),
		),
	)

}
Output:

true
false

func Last

func Last[T any](iter Iterator[T], n int) []T

Last consumes iter and returns the last n items. If iter yields fewer than n items, Last returns all of them.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Counter(10)

	last3 := iterator.Last(iter, 3)
	fmt.Println(last3)

	iter = iterator.Counter(2)
	last3 = iterator.Last(iter, 3)
	fmt.Println(last3)

}
Output:

[7 8 9]
[0 1]

func One

func One[T any](iter Iterator[T]) (T, bool)

One returns the only item yielded by iter. Returns false in the second return if iter yields zero or more than one item.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{"a"})
	item, ok := iterator.One(iter)
	fmt.Println(ok)
	fmt.Println(item)

	iter = iterator.Slice([]string{"a", "b"})
	item, ok = iterator.One(iter)
	fmt.Println(ok)

}
Output:

true
a
false

func Reduce

func Reduce[T any, U any](iter Iterator[T], initial U, f func(U, T) U) U

Reduce reduces iter to a single value using the reduction function f.

Example
package main

import (
	"fmt"
	"math"

	"github.com/bradenaw/juniper/iterator"
	"github.com/bradenaw/juniper/xmath"
)

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

	iter := iterator.Slice(x)
	sum := iterator.Reduce(iter, 0, func(x, y int) int { return x + y })
	fmt.Println(sum)

	iter = iterator.Slice(x)
	min := iterator.Reduce(iter, math.MaxInt, xmath.Min[int])
	fmt.Println(min)

}
Output:

6
1

Types

type Iterator

type Iterator[T any] interface {
	// Next advances the iterator and returns the next item. Once the iterator is finished, the
	// first return is meaningless and the second return is false. Note that the final value of the
	// iterator has true in the second return, and it's the following call that returns false in the
	// second return.
	//
	// Once Next returns false in the second return, it is expected that it will always return false
	// afterwards.
	Next() (T, bool)
}

Iterator is used to iterate over a sequence of values.

Iterators are lazy, meaning they do no work until a call to Next().

Iterators do not need to be fully consumed, callers may safely abandon an iterator before Next returns false.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Counter(5)

	for {
		item, ok := iter.Next()
		if !ok {
			break
		}
		fmt.Println(item)
	}

}
Output:

0
1
2
3
4

func Chan

func Chan[T any](c <-chan T) Iterator[T]

Chan returns an Iterator that yields the values received on c.

func Chunk

func Chunk[T any](iter Iterator[T], chunkSize int) Iterator[[]T]

Chunk returns an iterator over non-overlapping chunks of size chunkSize. The last chunk will be smaller than chunkSize if the iterator does not contain an even multiple.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{"a", "b", "c", "d", "e", "f", "g", "h"})

	chunked := iterator.Chunk(iter, 3)
	item, _ := chunked.Next()
	fmt.Println(item)
	item, _ = chunked.Next()
	fmt.Println(item)
	item, _ = chunked.Next()
	fmt.Println(item)

}
Output:

[a b c]
[d e f]
[g h]

func Compact

func Compact[T comparable](iter Iterator[T]) Iterator[T]

Compact elides adjacent duplicates from iter.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{"a", "a", "b", "c", "c", "c", "a"})
	compacted := iterator.Compact(iter)
	fmt.Println(iterator.Collect(compacted))

}
Output:

[a b c a]

func CompactFunc

func CompactFunc[T any](iter Iterator[T], eq func(T, T) bool) Iterator[T]

CompactFunc elides adjacent duplicates from iter, using eq to determine duplicates.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{
		"bank",
		"beach",
		"ghost",
		"goat",
		"group",
		"yaw",
		"yew",
	})
	compacted := iterator.CompactFunc(iter, func(a, b string) bool {
		return a[0] == b[0]
	})
	fmt.Println(iterator.Collect(compacted))

}
Output:

[bank ghost yaw]

func Counter

func Counter(n int) Iterator[int]

Counter returns an iterator that counts up from 0, yielding n items.

The following are equivalent:

for i := 0; i < n; i++ {
  fmt.Println(n)
}

iter := iterator.Counter(n)
for {
  item, ok := iter.Next()
  if !ok {
    break
  }
  fmt.Println(item)
}

func Empty added in v0.5.0

func Empty[T any]() Iterator[T]

Empty returns an iterator that yields no items.

func Filter

func Filter[T any](iter Iterator[T], keep func(T) bool) Iterator[T]

Filter returns an iterator that yields only the items from iter for which keep returns true.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]int{1, 2, 3, 4, 5, 6})

	evens := iterator.Filter(iter, func(x int) bool { return x%2 == 0 })
	fmt.Println(iterator.Collect(evens))

}
Output:

[2 4 6]

func First

func First[T any](iter Iterator[T], n int) Iterator[T]

First returns an iterator that yields the first n items from iter.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{"a", "b", "c", "d", "e"})

	first3 := iterator.First(iter, 3)
	fmt.Println(iterator.Collect(first3))

}
Output:

[a b c]

func Flatten

func Flatten[T any](iter Iterator[Iterator[T]]) Iterator[T]

Flatten returns an iterator that yields all items from all iterators yielded by iter.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]iterator.Iterator[int]{
		iterator.Slice([]int{0, 1, 2}),
		iterator.Slice([]int{3, 4, 5, 6}),
		iterator.Slice([]int{7}),
	})

	all := iterator.Flatten(iter)

	fmt.Println(iterator.Collect(all))

}
Output:

[0 1 2 3 4 5 6 7]

func Join

func Join[T any](iters ...Iterator[T]) Iterator[T]

Join returns an Iterator that returns all elements of iters[0], then all elements of iters[1], and so on.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Join(
		iterator.Counter(3),
		iterator.Counter(5),
		iterator.Counter(2),
	)

	fmt.Println(iterator.Collect(iter))

}
Output:

[0 1 2 0 1 2 3 4 0 1]

func Map

func Map[T any, U any](iter Iterator[T], f func(t T) U) Iterator[U]

Map transforms the results of iter using the conversion f.

func Repeat

func Repeat[T any](item T, n int) Iterator[T]

Repeat returns an iterator that yields item n times.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Repeat("a", 4)
	fmt.Println(iterator.Collect(iter))

}
Output:

[a a a a]

func Runs

func Runs[T any](iter Iterator[T], same func(a, b T) bool) Iterator[Iterator[T]]

Runs returns an iterator of iterators. The inner iterators yield contiguous elements from iter such that same(a, b) returns true for any a and b in the run.

The inner iterator should be drained before calling Next on the outer iterator.

same(a, a) must return true. If same(a, b) and same(b, c) both return true, then same(a, c) must also.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]int{2, 4, 0, 7, 1, 3, 9, 2, 8})

	parityRuns := iterator.Runs(iter, func(a, b int) bool {
		return a%2 == b%2
	})
	fmt.Println(iterator.Collect(iterator.Map(parityRuns, iterator.Collect[int])))

}
Output:

[[2 4 0] [7 1 3 9] [2 8]]

func Slice

func Slice[T any](s []T) Iterator[T]

Slice returns an iterator over the elements of s.

func While

func While[T any](iter Iterator[T], f func(T) bool) Iterator[T]

While returns an iterator that terminates before the first item from iter for which f returns false.

Example
package main

import (
	"fmt"

	"github.com/bradenaw/juniper/iterator"
)

func main() {
	iter := iterator.Slice([]string{
		"aardvark",
		"badger",
		"cheetah",
		"dinosaur",
		"egret",
	})

	beforeD := iterator.While(iter, func(s string) bool {
		return s < "d"
	})

	fmt.Println(iterator.Collect(beforeD))

}
Output:

[aardvark badger cheetah]

type Peekable

type Peekable[T any] interface {
	Iterator[T]
	// Peek returns the next item of the iterator if there is one without consuming it.
	//
	// If Peek returns a value, the next call to Next will return the same value.
	Peek() (T, bool)
}

Peekable allows viewing the next item from an iterator without consuming it.

func WithPeek

func WithPeek[T any](iter Iterator[T]) Peekable[T]

WithPeek returns iter with a Peek() method attached.

Jump to

Keyboard shortcuts

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