Documentation
¶
Overview ¶
Example (Decorate_string) ¶
package main
import (
"fmt"
"sync/atomic"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/iterable"
)
func main() {
src := "foo bar baz"
var num atomic.Int32
numListTitle := iterable.RepeatableFunc[string]{
FnV: func() string { return fmt.Sprintf("%d. ", num.Add(1)) },
N: 1,
}
m := hiter.StringsCollect(
9+((2 /*num*/ +2 /*. */ +1 /* */)*3),
hiter.SkipLast(
1,
hiter.Decorate(
numListTitle,
iterable.Repeatable[string]{V: " ", N: 1},
hiter.StringsSplitFunc(src, -1, hiter.StringsCutWord),
),
),
)
fmt.Printf("%s\n", m)
}
Output: 1. foo 2. bar 3. baz
Example (Merge_sort) ¶
Example_merge_sort implements slice version merge sort and re-implements iterator version of it.
package main
import (
"cmp"
"fmt"
"iter"
"math/rand/v2"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)
// avoiding xter dep
func limit[V any](seq iter.Seq[V], n int) iter.Seq[V] {
return func(yield func(V) bool) {
if n <= 0 {
return
}
for v := range seq {
if !yield(v) {
return
}
if n--; n <= 0 {
break
}
}
}
}
func mergeSortFunc[S ~[]T, T any](m S, cmp func(l, r T) int) S {
if len(m) <= 1 {
return m
}
left, right := m[:len(m)/2], m[len(m)/2:]
left = mergeSortFunc(left, cmp)
right = mergeSortFunc(right, cmp)
return mergeFunc(left, right, cmp)
}
func mergeFunc[S ~[]T, T any](l, r S, cmp func(l, r T) int) S {
m := make(S, len(l)+len(r))
var i int
for i = 0; len(l) > 0 && len(r) > 0; i++ {
if cmp(l[0], r[0]) < 0 {
m[i] = l[0]
l = l[1:]
} else {
m[i] = r[0]
r = r[1:]
}
}
for _, t := range l {
m[i] = t
i++
}
for _, t := range r {
m[i] = t
i++
}
return m
}
func mergeSortIterFunc[S ~[]T, T any](m S, cmp func(l, r T) int) iter.Seq[T] {
if len(m) <= 1 {
return slices.Values(m)
}
return func(yield func(T) bool) {
left, right := m[:len(m)/2], m[len(m)/2:]
leftIter := mergeSortIterFunc(left, cmp)
rightIter := mergeSortIterFunc(right, cmp)
for t := range xiter.MergeFunc(leftIter, rightIter, cmp) {
if !yield(t) {
return
}
}
}
}
type SliceLike[T any] interface {
hiter.Atter[T]
Len() int
}
var _ SliceLike[any] = sliceAdapter[any]{}
type sliceAdapter[T any] []T
func (s sliceAdapter[T]) At(i int) T {
return s[i]
}
func (s sliceAdapter[T]) Len() int {
return len(s)
}
type subbable[S SliceLike[T], T any] struct {
S S
i, j int
}
func (s subbable[S, T]) At(i int) T {
i = s.i + i
if i >= s.j {
panic("index out of range")
}
return s.S.At(i)
}
func (s subbable[S, T]) Len() int {
return s.j - s.i
}
func (s subbable[S, T]) Sub(i, j int) subbable[S, T] {
i = i + s.i
j = j + s.i
if i < 0 || j > s.j || i > j {
panic(fmt.Errorf("index out of range: i=%d, j=%d,len=%d", i, j, s.Len()))
}
return subbable[S, T]{
S: s.S,
i: i,
j: j,
}
}
func mergeSortAtterFunc[S SliceLike[T], T any](s S, cmp func(l, r T) int) iter.Seq[T] {
sub := subbable[S, T]{
S: s,
i: 0,
j: s.Len(),
}
return mergeSortSubbableFunc(sub, cmp)
}
func mergeSortSubbableFunc[S SliceLike[T], T any](s subbable[S, T], cmp func(l, r T) int) iter.Seq[T] {
if s.Len() <= 1 {
return hiter.OmitF(hiter.IndexAccessible(s, hiter.Range(0, s.Len())))
}
return func(yield func(T) bool) {
left, right := s.Sub(0, s.Len()/2), s.Sub(s.Len()/2, s.Len())
leftIter := mergeSortSubbableFunc(left, cmp)
rightIter := mergeSortSubbableFunc(right, cmp)
for t := range xiter.MergeFunc(leftIter, rightIter, cmp) {
if !yield(t) {
return
}
}
}
}
// Example_merge_sort implements slice version merge sort and re-implements iterator version of it.
func main() {
rng := hiter.RepeatFunc(func() int { return rand.N(20) }, -1)
fmt.Printf("merge sort: %t\n",
slices.IsSorted(mergeSortFunc(slices.Collect(limit(rng, 10)), cmp.Compare)),
)
fmt.Printf(
"merge sort iter: %t\n",
slices.IsSorted(
slices.Collect(
mergeSortIterFunc(slices.Collect(limit(rng, 10)), cmp.Compare),
),
),
)
fmt.Printf(
"merge sort atter: %t\n",
slices.IsSorted(
slices.Collect(
mergeSortAtterFunc(sliceAdapter[int](slices.Collect(limit(rng, 10))), cmp.Compare),
),
),
)
}
Output: merge sort: true merge sort iter: true merge sort atter: true
Example (Moving_average) ¶
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/collection"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)
func main() {
src := []int{1, 0, 1, 0, 1, 0, 5, 3, 2, 3, 4, 6, 5, 3, 6, 7, 7, 8, 9, 5, 7, 7, 8}
movingAverage := slices.Collect(
xiter.Map(
func(s []int) float64 {
return float64(collection.SumOf(slices.Values(s), func(e int) int { return e })) / float64(len(s))
},
hiter.Window(src, 5),
),
)
fmt.Printf("%#v\n", movingAverage)
}
Output: []float64{0.6, 0.4, 1.4, 1.8, 2.2, 2.6, 3.4, 3.6, 4, 4.2, 4.8, 5.4, 5.6, 6.2, 7.4, 7.2, 7.2, 7.2, 7.2}
Example (Range_map) ¶
package main
import (
"fmt"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/x/exp/xiter"
)
func main() {
for i := range hiter.LimitUntil(
func(i int) bool { return i < 50 },
xiter.Map(
func(i int) int { return i * 7 },
hiter.Range(0, 10),
),
) {
if i > 0 {
fmt.Printf(" ")
}
fmt.Printf("%d", i)
}
}
Output: 0 7 14 21 28 35 42 49
Index ¶
- func Alternate[V any](seqs ...iter.Seq[V]) iter.Seq[V]
- func Alternate2[K, V any](seqs ...iter.Seq2[K, V]) iter.Seq2[K, V]
- func AppendSeq2[S ~[]KeyValue[K, V], K, V any](s S, seq iter.Seq2[K, V]) S
- func Chan[V any](ctx context.Context, ch <-chan V) iter.Seq[V]
- func ChanSend[V any](ctx context.Context, c chan<- V, seq iter.Seq[V]) (v V, sentAll bool)
- func Decorate[V any](prepend, append Iterable[V], seq iter.Seq[V]) iter.Seq[V]
- func Decorate2[K, V any](prepend, append Iterable2[K, V], seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T]
- func Flatten[S ~[]E, E any](seq iter.Seq[S]) iter.Seq[E]
- func FlattenF[S1 ~[]E1, E1 any, E2 any](seq iter.Seq2[S1, E2]) iter.Seq2[E1, E2]
- func FlattenL[S2 ~[]E2, E1 any, E2 any](seq iter.Seq2[E1, S2]) iter.Seq2[E1, E2]
- func Heap[T any](h heap.Interface) iter.Seq[T]
- func IndexAccessible[A Atter[T], T any](a A, indices iter.Seq[int]) iter.Seq2[int, T]
- func JsonDecoder(dec *json.Decoder) iter.Seq2[json.Token, error]
- func LimitUntil[V any](f func(V) bool, seq iter.Seq[V]) iter.Seq[V]
- func LimitUntil2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func ListAll[T any](l *list.List) iter.Seq[T]
- func ListBackward[T any](l *list.List) iter.Seq[T]
- func ListElementAll[T any](ele *list.Element) iter.Seq[T]
- func ListElementBackward[T any](ele *list.Element) iter.Seq[T]
- func Omit[K any](seq iter.Seq[K]) func(yield func() bool)
- func Omit2[K, V any](seq iter.Seq2[K, V]) func(yield func() bool)
- func OmitF[K, V any](seq iter.Seq2[K, V]) iter.Seq[V]
- func OmitL[K, V any](seq iter.Seq2[K, V]) iter.Seq[K]
- func Pairs[K, V any](seq1 iter.Seq[K], seq2 iter.Seq[V]) iter.Seq2[K, V]
- func Range[T Numeric](start, end T) iter.Seq[T]
- func Repeat[V any](v V, n int) iter.Seq[V]
- func Repeat2[K, V any](k K, v V, n int) iter.Seq2[K, V]
- func RepeatFunc[V any](fnV func() V, n int) iter.Seq[V]
- func RepeatFunc2[K, V any](fnK func() K, fnV func() V, n int) iter.Seq2[K, V]
- func RingAll[T any](r *ring.Ring) iter.Seq[T]
- func RingBackward[T any](r *ring.Ring) iter.Seq[T]
- func Scan(scanner *bufio.Scanner) iter.Seq2[string, error]
- func Skip[V any](n int, seq iter.Seq[V]) iter.Seq[V]
- func Skip2[K, V any](n int, seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func SkipLast[V any](n int, seq iter.Seq[V]) iter.Seq[V]
- func SkipLast2[K, V any](n int, seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func SkipWhile[V any](f func(V) bool, seq iter.Seq[V]) iter.Seq[V]
- func SkipWhile2[K, V any](f func(K, V) bool, seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func StringsChunk(s string, n int) iter.Seq[string]
- func StringsCollect(sizeHint int, seq iter.Seq[string]) string
- func StringsCutNewLine(s string) (tokUntil int, skipUntil int)
- func StringsCutUpperCase(s string) (tokUntil int, skipUntil int)
- func StringsCutWord(s string) (tokUntil int, skipUntil int)
- func StringsRuneChunk(s string, n int) iter.Seq[string]
- func StringsSplitFunc(s string, n int, splitFn StringsCutterFunc) iter.Seq[string]
- func SyncMap[K, V any](m *sync.Map) iter.Seq2[K, V]
- func Tap[V any](tap func(V), seq iter.Seq[V]) iter.Seq[V]
- func Tap2[K, V any](tap func(K, V), seq iter.Seq2[K, V]) iter.Seq2[K, V]
- func Transpose[K, V any](seq iter.Seq2[K, V]) iter.Seq2[V, K]
- func Window[S ~[]E, E any](s S, n int) iter.Seq[S]
- func XmlDecoder(dec *xml.Decoder) iter.Seq2[xml.Token, error]
- type Atter
- type FuncIterable
- type FuncIterable2
- type IntoIterable
- type IntoIterable2
- type Iterable
- type Iterable2
- type KeyValue
- type KeyValues
- type Numeric
- type StringsCutterFunc
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Alternate ¶
Alternate returns an iterator that yields alternatively each seq from head to tail. The first exhausted seq stops the iterator.
func Alternate2 ¶
Alternate returns an iterator that yields alternatively each seq from head to tail. The first exhausted seq stops the iterator.
func AppendSeq2 ¶
AppendSeq2 appends the values from seq to the KeyValue slice and returns the extended slice.
func Chan ¶
Chan returns an iterator over ch. Either cancelling ctx or closing ch stops iteration. ctx is allowed to be nil.
func ChanSend ¶ added in v0.0.8
ChanSend sends values yielded from seq to c. sentAll is false if ctx is cancelled before all values from seq are sent.
func Decorate ¶
Decorate decorates seq by prepend and append, by yielding additional elements before and after seq yields.
func Decorate2 ¶
Decorate2 decorates seq by prepend and append, by yielding additional elements before and after seq yields.
func Enumerate ¶
Enumerate wraps seq so that former part of paired values has an index starting from 0. Each time values are yielded index is increased by 1.
func FlattenF ¶
FlattenF returns an iterator over pairs of slice and non-slice. While iterating over slices, the latter part of pair is repeated.
func FlattenL ¶
FlattenL returns an iterator over pairs of non-slice and slice. While iterating over slices, the former part of pair is repeated.
func Heap ¶
Heap returns an iterator over heap.Interface. Consuming iter.Seq[T] also consumes h. To avoid this, the caller must clone input h before passing to Heap.
func IndexAccessible ¶ added in v0.0.6
IndexAccessible returns an iterator over indices and values associated to it in the index-accessible object a. If indices generates an out-of-range index, the behavior is not defined and may differs among Atter implementations.
func JsonDecoder ¶ added in v0.0.6
JsonDecoder returns an iterator over json tokens.
func LimitUntil ¶
LimitUntil returns an iterator over seq that yields until f returns false.
func LimitUntil2 ¶
LimitUntil2 returns an iterator over seq that yields until f returns false.
func ListBackward ¶
ListBackward returns an iterator over l, traversing it backward by calling Back and Prev.
func ListElementAll ¶ added in v0.0.4
ListElementAll returns an iterator over from ele to end of the list.
func ListElementBackward ¶ added in v0.0.4
ListElementBackward returns an iterator over from ele to start of the list.
func Pairs ¶
Pairs combines seq1 and seq2 into an iterator over key-value pairs. If either stops, the returned iterator stops.
func Range ¶
Range produces an iterator that yields sequential Numeric values in range [start, end). Values start from `start` and steps toward `end` 1 by 1, increased or decreased depending on start < end or not.
func Repeat ¶
Repeat returns an iterator that generates v n times. If n < 0, the returned iterator repeats forever.
func Repeat2 ¶
Repeat2 returns an iterator that generates v n times. If n < 0, the returned iterator repeats forever.
func RepeatFunc ¶ added in v0.0.3
RepeatFunc returns an iterator that generates result from fnV n times. If n < 0, the returned iterator repeats forever.
func RepeatFunc2 ¶ added in v0.0.3
RepeatFunc2 returns an iterator that generates result of fnK and fnV n times. If n < 0, the returned iterator repeats forever.
func RingAll ¶
Ring returns an iterator over r. by traversing from r and consecutively calling Next.
func RingBackward ¶
RingBackward returns an iterator over r, traversing it backward starting from r and consecutively calling Prev.
func SkipLast2 ¶ added in v0.0.5
SkipLast returns an iterator over seq that skips last n key-value pairs.
func SkipWhile2 ¶
SkipWhile2 returns an iterator over seq that skips key-value pairs until f returns false.
func StringsChunk ¶
StringsChunk returns an iterator over non overlapping sub strings of n bytes. Sub slicing may cut in mid of utf8 sequences.
func StringsCollect ¶
StringsCollect reduces seq to a single string. sizeHint hints size of internal buffer. Correctly sized sizeHint may reduce allocation.
func StringsCutNewLine ¶
StringsCutNewLine is used with StringsSplitFunc. The input strings will be splitted at "\n". It also skips "\r" preceding "\n".
func StringsCutUpperCase ¶
StringsCutUpperCase is a split function for a StringsSplitFunc that splits "UpperCasedWords" into "Upper" "Cased" "Words"
func StringsCutWord ¶ added in v0.0.5
StringsCutWord is a split function for a StringsSplitFunc that returns each space-separated word of text, with surrounding spaces deleted. It will never return an empty string. The definition of space is set by unicode.IsSpace.
func StringsRuneChunk ¶
StringsRuneChunk returns an iterator over non overlapping sub strings of n utf8 characters.
func StringsSplitFunc ¶
StringsSplitFunc returns an iterator over sub string of s cut by splitFn. When n > 0, StringsSplitFunc cuts only n times and the returned iterator yields rest of string after n sub strings, if non empty. The sub strings from the iterator overlaps if splitFn decides so. splitFn is allowed to return negative offsets. In that case the returned iterator immediately yields rest of s and stops iteration.
func SyncMap ¶
SyncMap returns an iterator over m. Breaking Seq2 may stop producing more data, however it may still be O(N).
func XmlDecoder ¶ added in v0.0.6
XmlDecoder returns an iterator over xml tokens. The first non-nil error encountered stops iteration. Callers should call xml.CopyToken before going to next iteration if they need to retain tokens.
Types ¶
type FuncIterable ¶
func (FuncIterable[V]) IntoIter ¶
func (f FuncIterable[V]) IntoIter() iter.Seq[V]
func (FuncIterable[V]) Iter ¶
func (f FuncIterable[V]) Iter() iter.Seq[V]
type FuncIterable2 ¶
func (FuncIterable2[K, V]) IntoIter2 ¶
func (f FuncIterable2[K, V]) IntoIter2() iter.Seq2[K, V]
func (FuncIterable2[K, V]) Iter2 ¶
func (f FuncIterable2[K, V]) Iter2() iter.Seq2[K, V]
type IntoIterable ¶
IntoIterable wraps basic IntoIter2 method.
Calling IntoIter may mutate underlying state. Therefore calling the method again may also not yield same result.
type IntoIterable2 ¶
IntoIterable2 wraps basic IntoIter2 method.
Calling IntoIter2 may mutate underlying state. Therefore calling the method again may also not yield same result.
type Iterable ¶
Iterable wraps basic Iter method.
Iter should always return iterators that yield same set of data.
type Iterable2 ¶
Iterable2 wraps basic Iter2 method.
Iter2 should always return iterators that yield same set of data.
type StringsCutterFunc ¶
StringsCutterFunc is used with StringsSplitFunc to cut string from head. s[:tokUntil] is yielded through StringsSplitFunc. s[tokUntil:skipUntil] will be ignored.