Skip to content
catena
v1.1.0
Theme

This content is for v1.1.0. Switch to the latest version for up-to-date documentation.

List

List and the Seq2 bridge: when the data is small and already in memory, eager evaluation with exact preallocation beats a lazy chain — and the two worlds convert explicitly, in both directions.

Run it: go run ./examples/08-list

// List and the Seq2 bridge: when the data is small and already in memory,
// eager evaluation with exact preallocation beats a lazy chain — and the
// two worlds convert explicitly, in both directions.
package main
import (
"fmt"
"strings"
"github.com/NerdMeNot/catena"
)
func main() {
// A List IS a []T — construct it like one, index it like one.
words := catena.List[string]{"the", "chain", "holds", "when", "every", "link", "does"}
fmt.Println("len:", words.Len(), "third word:", words.At(2))
// The whole Seq operation set exists eagerly. Each stage returns a
// finished List (Map preallocates exactly), and the semantics are
// conformance-checked to match the lazy version over AsSeq().
shouting := words.
Filter(func(w string) bool { return len(w) > 3 }).
Map(strings.ToUpper)
fmt.Println("emphasis:", shouting)
// FoldRight exists only on List — a right fold needs the whole
// sequence anyway, and a List already is one.
nested := words.FoldRight("∎", func(w, acc string) string {
return "(" + w + " " + acc + ")"
})
fmt.Println("right-nested:", nested)
// Append never aliases: the result always has a fresh backing array,
// like every other List transform — unlike the builtin.
base := catena.List[int]{1, 2, 3}
grown := base.Append(4, 5)
grown[0] = 99
fmt.Println("base untouched:", base, "grown:", grown)
// Cross to lazy when short-circuiting starts to matter…
firstLong, _ := words.AsSeq().Find(func(w string) bool { return len(w) >= 5 })
fmt.Println("first long word:", firstLong)
// …and back to eager when you want a materialized result.
lengths := words.AsSeq().
Map(func(w string) int { return len(w) }).
ToList()
fmt.Println("lengths:", lengths)
// Seq2 is the bridge to pair-shaped data: maps in, pairs along,
// and either a Seq (MapTo) or a map (CollectMap) out.
tally := catena.FromSlice(lengths).TallyBy(catena.Self[int])
report := catena.FromMap(tally).
Filter(func(length, count int) bool { return count > 1 }).
MapTo(func(length, count int) string {
return fmt.Sprintf("%d words of length %d", count, length)
}).
Collect()
fmt.Println("common lengths:", report)
// WithIndex pairs elements with positions; Unzip splits a pair
// sequence back into its two sides in one pass.
idx, vals := catena.Unzip(words.AsSeq().Take(3).WithIndex())
fmt.Println("positions:", idx, "values:", vals)
}

View on GitHub