Documentation
¶
Overview ¶
This package only contains some example which did not fit to other packages. See other packages' godoc for usage.
Example (Async_chunk) ¶
package main
import (
"context"
"fmt"
"sync"
"time"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/async"
)
func main() {
var (
wg sync.WaitGroup
in = make(chan int)
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
wg.Add(1)
go func() {
defer wg.Done()
ticker := time.NewTicker(500 * time.Nanosecond)
defer ticker.Stop()
_, _ = hiter.ChanSend(ctx, in, hiter.Tap(func(int) { <-ticker.C }, hiter.Range(0, 20)))
close(in)
}()
first := true
var count int
for c := range async.Chunk(time.Microsecond, 5, hiter.Chan(ctx, in)) {
count++
for _, i := range c {
if !first {
fmt.Print(", ")
}
first = false
fmt.Printf("%d", i)
}
}
fmt.Println()
wg.Wait()
fmt.Printf("count > 0 = %t\n", count > 0)
}
Output: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 count > 0 = true
Example (Async_worker_channel) ¶
Example async worker channel demonstrates usage of [hiter.Chan], [hiter.ChanSend]. It sends values from seq to worker running on separates goroutines. Workers work on values and then send results back to the main goroutine.
package main
import (
"context"
"fmt"
"maps"
"slices"
"sync"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/iterable"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
works := []string{"foo", "bar", "baz"}
in := make(chan string, 5)
out := make(chan hiter.KeyValue[string, error])
var wg sync.WaitGroup
wg.Add(3)
for range 3 {
go func() {
defer wg.Done()
_, _ = hiter.ChanSend(
ctx,
out,
hiter.Map(
func(s string) hiter.KeyValue[string, error] {
return hiter.KeyValue[string, error]{
K: "✨" + s + "✨" + s + "✨",
V: nil,
}
},
hiter.Chan(ctx, in),
),
)
}()
}
var wg2 sync.WaitGroup
wg2.Add(1)
go func() {
defer wg2.Done()
wg.Wait()
close(out)
}()
_, _ = hiter.ChanSend(ctx, in, slices.Values(works))
close(in)
results := maps.Collect(hiter.FromKeyValue(hiter.Chan(ctx, out)))
for result, err := range iterable.MapSorted[string, error](results).Iter2() {
fmt.Printf("result = %s, err = %v\n", result, err)
}
wg2.Wait()
}
Output: result = ✨bar✨bar✨, err = <nil> result = ✨baz✨baz✨, err = <nil> result = ✨foo✨foo✨, err = <nil>
Example (Async_worker_map) ¶
Example async worker map demonstrates usage of async.Map. At the surface it is similar to [hiter.Map2]. Actually it calls mapper in separate goroutine. If you don't care about order of element, just send values to workers through a channel and send back through another channel.
package main
import (
"context"
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter/async"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
works := []string{"foo", "bar", "baz"}
// The order is kept.
for result, err := range async.Map(
ctx,
/*queueLimit*/ 10,
/*workerLimit*/ 5,
/*mapper*/ func(ctx context.Context, s string) (string, error) {
return "✨" + s + "✨" + s + "✨", nil
},
slices.Values(works),
) {
fmt.Printf("result = %s, err = %v\n", result, err)
}
}
Output: result = ✨foo✨foo✨, err = <nil> result = ✨bar✨bar✨, err = <nil> result = ✨baz✨baz✨, err = <nil>
Example (Async_worker_map_graceful_cancellation) ¶
package main
import (
"context"
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter/async"
"github.com/ngicks/go-iterator-helper/hiter/mapper"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
works := []string{"foo", "bar", "baz"}
workerCtx, cancelWorker := context.WithCancel(context.Background())
defer cancelWorker()
for result, err := range async.Map(
ctx,
/*queueLimit*/ 1,
/*workerLimit*/ 1,
/*mapper*/ func(ctx context.Context, s string) (string, error) {
combined, cancel := context.WithCancel(ctx)
defer cancel()
go func() {
select {
case <-ctx.Done():
case <-combined.Done():
case <-workerCtx.Done():
}
cancel()
}()
if combined.Err() != nil {
return "", combined.Err()
}
return "✨" + s + "✨" + s + "✨", nil
},
mapper.Cancellable(1, workerCtx, slices.Values(works)),
) {
fmt.Printf("result = %s, err = %v\n", result, err)
cancelWorker()
}
}
Output: result = ✨foo✨foo✨, err = <nil> result = ✨bar✨bar✨, err = <nil>
Example (Concat) ¶
Example_concat demonstrates combining multiple iterators
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
first := slices.Values([]int{1, 2, 3})
second := slices.Values([]int{10, 11})
third := slices.Values([]int{20, 21, 22})
combined := hiter.Concat(first, second, third)
fmt.Println("Combined:", slices.Collect(combined))
}
Output: Combined: [1 2 3 10 11 20 21 22]
Example (CreatingIterators) ¶
Example_creatingIterators demonstrates creating iterators from various sources
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// From slices
slice_iter := slices.Values([]int{1, 2, 3})
fmt.Println("From slice:", slices.Collect(slice_iter))
// Using Range
range_iter := hiter.Range(10, 15)
fmt.Println("Range:", slices.Collect(range_iter))
// Using Repeat
repeat_iter := hiter.Repeat("hi", 3)
fmt.Println("Repeat:", slices.Collect(repeat_iter))
// Using Once
once_iter := hiter.Once(42)
fmt.Println("Once:", slices.Collect(once_iter))
}
Output: From slice: [1 2 3] Range: [10 11 12 13 14] Repeat: [hi hi hi] Once: [42]
Example (Dec_enc_round_trip) ¶
package main
import (
"bytes"
"encoding/json"
"fmt"
"maps"
"os"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/encodingiter"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
)
func main() {
src := []byte(`
{"foo":"foo"}
{"bar":"bar"}
{"baz":"baz"}
`)
rawDec := json.NewDecoder(bytes.NewReader(src))
dec := errbox.New(encodingiter.Decode[map[string]string](rawDec))
enc := json.NewEncoder(os.Stdout)
err := encodingiter.Encode(
enc,
hiter.Map(
func(m map[string]string) map[string]string {
return maps.Collect(
hiter.Map2(
func(k, v string) (string, string) { return k + k, v + v },
maps.All(m),
),
)
},
dec.IntoIter(),
),
)
fmt.Printf("dec error = %v\n", dec.Err())
fmt.Printf("enc error = %v\n", err)
}
Output: {"foofoo":"foofoo"} {"barbar":"barbar"} {"bazbaz":"bazbaz"} dec error = <nil> enc error = <nil>
Example (ErrboxJSON) ¶
Example_errboxJSON demonstrates error handling in JSON streams
package main
import (
"bytes"
"encoding/json"
"fmt"
"github.com/ngicks/go-iterator-helper/hiter/encodingiter"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
)
func main() {
// JSON stream with an invalid entry
jsonData := `{"id":1,"name":"Alice"}
{"id":2,"name":"Bob"}
{"invalid json syntax
{"id":3,"name":"Charlie"}`
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
}
decoder := json.NewDecoder(bytes.NewReader([]byte(jsonData)))
jsonBox := errbox.New(encodingiter.Decode[Person](decoder))
var validRecords []Person
for person := range jsonBox.IntoIter() {
validRecords = append(validRecords, person)
fmt.Printf("Decoded: %+v\n", person)
}
// Check for errors after processing
if err := jsonBox.Err(); err != nil {
fmt.Printf("Stream error after %d valid records: %v\n", len(validRecords), err)
}
}
Output: Decoded: {ID:1 Name:Alice} Decoded: {ID:2 Name:Bob} Stream error after 2 valid records: invalid character '\n' in string literal
Example (ErrboxXML) ¶
Example_errboxXML demonstrates error handling in XML streams
package main
import (
"bytes"
"encoding/xml"
"fmt"
"github.com/ngicks/go-iterator-helper/hiter/encodingiter"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
)
func main() {
// XML stream with mixed valid and invalid entries
xmlData := `<item><id>1</id><name>First</name></item>
<item><id>2</id><name>Second</name></item>
<item><id>3<name>Third</name></item>
<item><id>4</id><name>Fourth</name></item>`
type Item struct {
ID int `xml:"id"`
Name string `xml:"name"`
}
decoder := xml.NewDecoder(bytes.NewReader([]byte(xmlData)))
xmlBox := errbox.New(encodingiter.Decode[Item](decoder))
validCount := 0
for item := range xmlBox.IntoIter() {
validCount++
fmt.Printf("Valid item: %+v\n", item)
}
if err := xmlBox.Err(); err != nil {
fmt.Printf("Parsing stopped after %d valid items: error in XML\n", validCount)
}
}
Output: Valid item: {ID:1 Name:First} Valid item: {ID:2 Name:Second} Parsing stopped after 2 valid items: error in XML
Example (Error_handle) ¶
Example error handle demonstrates various way to handle error.
package main
import (
"errors"
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/errbox"
"github.com/ngicks/go-iterator-helper/hiter/mapper"
)
func main() {
var (
errSample = errors.New("sample")
errSample2 = errors.New("sample2")
)
erroneous := hiter.Pairs(
hiter.Range(0, 6),
hiter.Concat(
hiter.Repeat(error(nil), 2),
hiter.Repeat(errSample2, 2),
hiter.Once(errSample),
hiter.Once(error(nil)),
),
)
fmt.Println("TryFind:")
v, idx, err := hiter.TryFind(func(i int) bool { return i > 0 }, erroneous)
fmt.Printf("v = %d, idx = %d, err = %v\n", v, idx, err)
v, idx, err = hiter.TryFind(func(i int) bool { return i > 5 }, erroneous)
fmt.Printf("v = %d, idx = %d, err = %v\n", v, idx, err)
fmt.Println()
fmt.Println("TryForEach:")
err = hiter.TryForEach(func(i int) { fmt.Printf("i = %d\n", i) }, erroneous)
fmt.Printf("err = %v\n", err)
fmt.Println()
fmt.Println("TryReduce:")
collected, err := hiter.TryReduce(func(c []int, i int) []int { return append(c, i) }, nil, erroneous)
fmt.Printf("collected = %#v, err = %v\n", collected, err)
fmt.Println()
fmt.Println("HandleErr:")
var handled error
collected = slices.Collect(
mapper.HandleErr(
func(i int, err error) bool {
handled = err
return errors.Is(err, errSample2)
},
erroneous,
),
)
fmt.Printf("collected = %#v, err = %v\n", collected, handled)
fmt.Println()
fmt.Println("*errbox.Box:")
box := errbox.New(erroneous)
collected = slices.Collect(box.IntoIter())
fmt.Printf("collected = %#v, err = %v\n", collected, box.Err())
fmt.Println()
}
Output: TryFind: v = 1, idx = 1, err = <nil> v = 0, idx = -1, err = sample2 TryForEach: i = 0 i = 1 err = sample2 TryReduce: collected = []int{0, 1}, err = sample2 HandleErr: collected = []int{0, 1}, err = sample *errbox.Box: collected = []int{0, 1}, err = sample2
Example (Flatten) ¶
Example_flatten demonstrates flattening nested structures
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Nested arrays representing grouped data
grouped := [][]string{
{"apple", "banana"},
{"carrot"},
{"dog", "elephant", "fox"},
{"guitar"},
}
// Flatten the nested structure
flattened := hiter.Flatten(slices.Values(grouped))
fmt.Println("Grouped:", grouped)
fmt.Println("Flattened:", slices.Collect(flattened))
}
Output: Grouped: [[apple banana] [carrot] [dog elephant fox] [guitar]] Flattened: [apple banana carrot dog elephant fox guitar]
Example (FlattenF) ¶
Example_flattenF demonstrates FlattenF for pair flattening
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Categories with items
categories := [][]string{{"fruits", "vegetables"}, {"proteins"}}
counts := []int{10, 5}
// FlattenF expands the first element (categories) while keeping the second
expanded := hiter.FlattenF(hiter.Pairs(slices.Values(categories), slices.Values(counts)))
fmt.Println("Category-Count pairs:")
for category, count := range expanded {
fmt.Printf(" %s: %d items\n", category, count)
}
}
Output: Category-Count pairs: fruits: 10 items vegetables: 10 items proteins: 5 items
Example (FlattenL) ¶
Example_flattenL demonstrates FlattenL for second element flattening
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Products with multiple prices (different stores)
products := []string{"laptop", "phone"}
prices := [][]float64{{999.99, 1099.99, 899.99}, {599.99, 649.99}}
// FlattenL expands the second element (prices) while keeping the first
expanded := hiter.FlattenL(hiter.Pairs(slices.Values(products), slices.Values(prices)))
fmt.Println("Product-Price combinations:")
for product, price := range expanded {
fmt.Printf(" %s: $%.2f\n", product, price)
}
}
Output: Product-Price combinations: laptop: $999.99 laptop: $1099.99 laptop: $899.99 phone: $599.99 phone: $649.99
Example (MapAndFilter) ¶
Example_mapAndFilter demonstrates transforming iterators
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5, 6})
// Map to double values
doubled := hiter.Map(func(n int) int { return n * 2 }, numbers)
fmt.Println("Doubled:", slices.Collect(doubled))
// Filter even numbers
numbers2 := slices.Values([]int{1, 2, 3, 4, 5, 6})
evens := hiter.Filter(func(n int) bool { return n%2 == 0 }, numbers2)
fmt.Println("Evens:", slices.Collect(evens))
// Chain Map and Filter
numbers3 := slices.Values([]int{1, 2, 3, 4, 5, 6})
doubled_evens := hiter.Filter(
func(n int) bool { return n%4 == 0 },
hiter.Map(func(n int) int { return n * 2 }, numbers3),
)
fmt.Println("Doubled evens:", slices.Collect(doubled_evens))
}
Output: Doubled: [2 4 6 8 10 12] Evens: [2 4 6] Doubled evens: [4 8 12]
Example (Peek_and_continue) ¶
package main
import (
"fmt"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/iterable"
)
func main() {
// iterator that yields 0 to 9 sequentially.
src := hiter.Range(0, 10)
fmt.Println("It replays data if break-ed and resumed.")
count := 3
first := true
for v := range src {
count--
if count < 0 {
break
}
if !first {
fmt.Print(", ")
}
first = false
fmt.Printf("%d", v)
}
fmt.Println()
fmt.Println("break and resume")
first = true
for v := range hiter.Limit(3, src) {
if !first {
fmt.Print(", ")
}
first = false
fmt.Printf("%d", v)
}
fmt.Print("\n\n")
fmt.Println("converting it to be resumable.")
resumable := iterable.NewResumable(src)
v0, _ := hiter.First(resumable.IntoIter())
fmt.Printf("first: %d\n", v0)
v1, _ := hiter.First(resumable.IntoIter())
fmt.Printf("second: %d\n", v1)
fmt.Println()
fmt.Println("reconnect them to whole iterator.")
first = true
for v := range hiter.Concat(hiter.Once(v0), hiter.Once(v1), resumable.IntoIter()) {
if !first {
fmt.Print(", ")
}
first = false
fmt.Printf("%d", v)
}
fmt.Println()
fmt.Println("\nYou can achieve above also with iterable.Peekable")
peekable := iterable.NewPeekable(src)
fmt.Printf("%#v\n", peekable.Peek(5))
first = true
for v := range peekable.IntoIter() {
if !first {
fmt.Print(", ")
}
first = false
fmt.Printf("%d", v)
}
fmt.Println()
}
Output: It replays data if break-ed and resumed. 0, 1, 2 break and resume 0, 1, 2 converting it to be resumable. first: 0 second: 1 reconnect them to whole iterator. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 You can achieve above also with iterable.Peekable []int{0, 1, 2, 3, 4} 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Example (Reduce) ¶
Example_reduce demonstrates aggregation with Reduce
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
numbers := slices.Values([]int{1, 2, 3, 4, 5})
// Sum using Reduce
sum := hiter.Reduce(func(acc, val int) int { return acc + val }, 0, numbers)
fmt.Println("Sum:", sum)
// Product using Reduce
numbers2 := slices.Values([]int{1, 2, 3, 4, 5})
product := hiter.Reduce(func(acc, val int) int { return acc * val }, 1, numbers2)
fmt.Println("Product:", product)
}
Output: Sum: 15 Product: 120
Example (ReduceGroup) ¶
Example_reduceGroup demonstrates grouping and aggregation
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Group by key and sum values
pairs := hiter.Pairs(
slices.Values([]string{"fruit", "vegetable", "fruit", "fruit", "vegetable"}),
slices.Values([]int{10, 20, 30, 15, 25}),
)
grouped := hiter.ReduceGroup(
func(acc, val int) int { return acc + val },
0,
pairs,
)
fmt.Println("Grouped sums:", grouped)
}
Output: Grouped sums: map[fruit:55 vegetable:45]
Example (Resumable) ¶
Example_resumable demonstrates pausable and resumable iteration
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/iterable"
)
func main() {
// Create a resumable iterator from a range
source := hiter.Range(1, 10)
resumable := iterable.NewResumable(source)
// Process in batches
fmt.Println("Processing in batches:")
// Batch 1: Take first 3 elements
batch1 := hiter.Limit(3, resumable.IntoIter())
fmt.Println("Batch 1:", slices.Collect(batch1))
// Batch 2: Take next 3 elements
batch2 := hiter.Limit(3, resumable.IntoIter())
fmt.Println("Batch 2:", slices.Collect(batch2))
// Batch 3: Get remaining elements
remaining := resumable.IntoIter()
fmt.Println("Remaining:", slices.Collect(remaining))
}
Output: Processing in batches: Batch 1: [1 2 3] Batch 2: [4 5 6] Remaining: [7 8 9]
Example (ResumablePeek) ¶
Example_resumablePeek demonstrates peeking with resumable iterators
package main
import (
"fmt"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/iterable"
)
func main() {
// Data stream to process
data := hiter.Range(100, 106)
resumable := iterable.NewResumable(data)
// Peek at first element without consuming
first, _ := hiter.First(resumable.IntoIter())
fmt.Printf("Peeked first: %d\n", first)
// Process all elements (including the peeked one)
fmt.Print("All elements: ")
for val := range resumable.IntoIter() {
fmt.Printf("%d ", val)
}
fmt.Println()
}
Output: Peeked first: 100 All elements: 101 102 103 104 105
Example (StringJoin) ¶
Example_stringJoin demonstrates joining strings with an iterator
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter/stringsiter"
)
func main() {
words := slices.Values([]string{"go", "iterator", "helper"})
collected := stringsiter.Collect(words)
fmt.Println("Collected:", collected)
joined := stringsiter.Join("-", words)
fmt.Println("Joined:", joined)
// Join with different separator
parts := slices.Values([]string{"2024", "12", "25"})
date := stringsiter.Join("/", parts)
fmt.Println("Date:", date)
}
Output: Collected: goiteratorhelper Joined: go-iterator-helper Date: 2024/12/25
Example (Teeing) ¶
package main
import (
"fmt"
"sync"
"github.com/ngicks/go-iterator-helper/hiter"
"github.com/ngicks/go-iterator-helper/hiter/tee"
)
func main() {
src := hiter.Range(0, 5)
seqPiped, seq := tee.TeeSeqPipe(0, src)
var found bool
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
found = hiter.Contains(3, seqPiped.IntoIter())
// Don't forget to discard all elements from seq!
// Without this, tee could not proceed.
hiter.Discard(seqPiped.IntoIter())
}()
for i := range hiter.Map(func(i int) int { return i * i }, seq.IntoIter()) {
fmt.Printf("i = %02d\n", i)
}
wg.Wait()
fmt.Printf("\nfound=%t\n", found)
}
Output: i = 00 i = 01 i = 04 i = 09 i = 16 found=true
Example (TryFind) ¶
Example_tryFind demonstrates error-aware searching
package main
import (
"errors"
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Create an iterator with potential errors
data := hiter.Pairs(
slices.Values([]int{1, 2, 3, 4, 5}),
hiter.Concat(
hiter.Repeat(error(nil), 2),
hiter.Once(errors.New("processing error")),
hiter.Repeat(error(nil), 2),
),
)
// TryFind stops on first error
val, idx, err := hiter.TryFind(func(n int) bool { return n > 2 }, data)
if err != nil {
fmt.Printf("Error encountered at search: %v\n", err)
fmt.Printf("Last value: %d, index: %d\n", val, idx)
} else {
fmt.Printf("Found: value=%d at index=%d\n", val, idx)
}
}
Output: Error encountered at search: processing error Last value: 0, index: -1
Example (TryForEach) ¶
Example_tryForEach demonstrates error-aware iteration
package main
import (
"errors"
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Create an iterator with errors at specific positions
data := hiter.Pairs(
slices.Values([]string{"apple", "banana", "cherry", "date"}),
hiter.Concat(
hiter.Repeat(error(nil), 2),
hiter.Once(errors.New("bad fruit")),
hiter.Once(error(nil)),
),
)
count := 0
err := hiter.TryForEach(func(fruit string) {
count++
fmt.Printf("Processing: %s\n", fruit)
}, data)
if err != nil {
fmt.Printf("Stopped after %d items due to: %v\n", count, err)
} else {
fmt.Printf("Processed all %d items successfully\n", count)
}
}
Output: Processing: apple Processing: banana Stopped after 2 items due to: bad fruit
Example (WindowMovingAverage) ¶
Example_windowMovingAverage demonstrates sliding window for moving averages
package main
import (
"fmt"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Data for moving average calculation
data := []int{10, 20, 30, 40, 50, 60, 70, 80}
windowSize := 3
// Create sliding windows
windows := hiter.Window(data, windowSize)
// Calculate average for each window
averages := hiter.Map(func(window []int) float64 {
sum := hiter.Sum(slices.Values(window))
return float64(sum) / float64(len(window))
}, windows)
fmt.Println("Data:", data)
fmt.Printf("Moving averages (window=%d): %.1f\n", windowSize, slices.Collect(averages))
}
Output: Data: [10 20 30 40 50 60 70 80] Moving averages (window=3): [20.0 30.0 40.0 50.0 60.0 70.0]
Example (WindowSeq) ¶
Example_windowSeq demonstrates WindowSeq with iterator-based windows
package main
import (
"fmt"
"iter"
"slices"
"github.com/ngicks/go-iterator-helper/hiter"
)
func main() {
// Temperature readings
temperatures := []float64{22.5, 23.0, 22.8, 23.5, 24.0, 23.8, 23.2}
// Create iterator-based sliding windows
windowSeqs := hiter.WindowSeq(3, slices.Values(temperatures))
// Find max temperature in each window
maxTemps := hiter.Map(func(window iter.Seq[float64]) float64 {
max := 0.0
for temp := range window {
if temp > max {
max = temp
}
}
return max
}, windowSeqs)
fmt.Printf("Max temperatures in sliding windows: %.1f\n", slices.Collect(maxTemps))
}
Output: Max temperatures in sliding windows: [23.0 23.5 24.0 24.0 24.0]
Directories
¶
| Path | Synopsis |
|---|---|
|
hiter defines iterator sources from various inputs, adapters, collectors.
|
hiter defines iterator sources from various inputs, adapters, collectors. |
|
async
The package async defines asynchronous adapters.
|
The package async defines asynchronous adapters. |
|
bufioiter
bufioiter defines iterator source/collector that corresponds to std library `bufio`.
|
bufioiter defines iterator source/collector that corresponds to std library `bufio`. |
|
containeriter
containeriter defines iterator source/collector that corresponds to std library `container/*`.
|
containeriter defines iterator source/collector that corresponds to std library `container/*`. |
|
cryptoiter
cryptoiter defines iterator source/collector that corresponds to std `crypto/*`.
|
cryptoiter defines iterator source/collector that corresponds to std `crypto/*`. |
|
databaseiter
databaseiter defines iterator source/collector that corresponds to std library `database/*`.
|
databaseiter defines iterator source/collector that corresponds to std library `database/*`. |
|
encodingiter
encodingiter defines iterator source/collector that corresponds to std library `encoding` and all its descendants (`encoding/*`)
|
encodingiter defines iterator source/collector that corresponds to std library `encoding` and all its descendants (`encoding/*`) |
|
errbox
errbox boxes iter.Seq[V, error] and converts to iter.Seq[V].
|
errbox boxes iter.Seq[V, error] and converts to iter.Seq[V]. |
|
ioiter
ioiter defines iterator source/collector that corresponds to std library `io/*`.
|
ioiter defines iterator source/collector that corresponds to std library `io/*`. |
|
iterable
Wrapper for iterable objects; heap, list, ring, slice, map, channel, etc.
|
Wrapper for iterable objects; heap, list, ring, slice, map, channel, etc. |
|
iterreader
iterreader defines functions that converts an iterator to io.Reader.
|
iterreader defines functions that converts an iterator to io.Reader. |
|
mapper
package mapper is collection of small mapping helpers.
|
package mapper is collection of small mapping helpers. |
|
mathiter
mathiter defines iterator source/collector that corresponds to std `math/*`.
|
mathiter defines iterator source/collector that corresponds to std `math/*`. |
|
reflectiter
reflectiter defines iterator source/collector that corresponds to std library `reflect`.
|
reflectiter defines iterator source/collector that corresponds to std library `reflect`. |
|
stringsiter
stringsiter defines iterator source/collector that corresponds to std library `strings`.
|
stringsiter defines iterator source/collector that corresponds to std library `strings`. |
|
internal
|
|
|
x
|
|
|
exp/xiter
Code copied from
|
Code copied from |