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.

Combining

Putting two or more sequences together, or pairing a sequence with itself. Concat and Chain are lazy in both operands; Zip pulls its second operand, and the set operations buffer theirs.

func (s Seq[T]) Concat(others ...Seq[T]) Seq[T]

Concat yields s, then each of the others in order.

fmt.Println(catena.Of(1, 2).Concat(catena.Of(3), catena.Of(4, 5)).Collect())
[1 2 3 4 5]
func (s Seq[T]) Append(vals ...T) Seq[T]

Append yields s, then the given values.

fmt.Println(catena.Of("a").Append("b", "c").Collect())
[a b c]
func (s Seq[T]) Prepend(vals ...T) Seq[T]

Prepend yields the given values, then s.

fmt.Println(catena.Of("c").Prepend("a", "b").Collect())
[a b c]
func Chain[T any](seqs ...Seq[T]) Seq[T]

Chain yields each sequence’s elements in order.

// The variadic form, for when the sequences are in a slice already.
fmt.Println(catena.Chain(catena.Of(1), catena.Of(2), catena.Of(3)).Collect())
[1 2 3]
func (s Seq[T]) Zip[U any](other Seq[U]) Seq2[T, U]

Zip pairs elements of s with elements of other, stopping at the shorter side. The receiver drives; other is consumed through iter.Pull (its cleanup always runs). other is pulled once per emitted pair; the receiver is consumed one element past the pair count when other is shorter.

// Pairs elements positionally and stops at the shorter side.
names := catena.Of("ada", "bob", "eve")
scores := catena.Of(90, 85)
fmt.Println(names.Zip(scores).
MapTo(func(n string, s int) string { return fmt.Sprintf("%s=%d", n, s) }).
Collect())
[ada=90 bob=85]
func (s Seq[T]) ZipWithNext() Seq2[T, T]

ZipWithNext yields each adjacent pair (element, next element). Empty and single-element input yield nothing.

// Each element paired with its successor — deltas, gaps, transitions.
fmt.Println(catena.Of(3, 7, 12).ZipWithNext().
MapTo(func(a, b int) int { return b - a }).
Collect())
[4 5]
func (s Seq[T]) WithIndex() Seq2[int, T]

WithIndex pairs each element with its index, counting from 0.

fmt.Println(catena.Of("a", "b").WithIndex().
MapTo(func(i int, s string) string { return fmt.Sprintf("%d%s", i, s) }).
Collect())
[0a 1b]
func (s Seq[T]) JoinBy[U any, K comparable, R any](
other Seq[U],
leftKey func(T) K, rightKey func(U) K,
combine func(T, U) R,
) Seq[R]

JoinBy is a relational inner join: it pairs each element of s with every element of other sharing the same key and yields combine for each pair. Unmatched elements on either side are dropped; duplicate keys produce the cross product per key. Output order is left encounter order, then right encounter order within a key.

// A relational inner join: unmatched rows on either side are dropped,
// and duplicate keys produce the cross product.
type order struct {
Customer int
Amount int
}
type customer struct {
ID int
Name string
}
orders := catena.Of(order{1, 30}, order{2, 10}, order{9, 99})
customers := catena.Of(customer{1, "ada"}, customer{2, "bob"})
fmt.Println(orders.JoinBy(customers,
func(o order) int { return o.Customer },
func(c customer) int { return c.ID },
func(o order, c customer) string { return fmt.Sprintf("%s:%d", c.Name, o.Amount) },
).Collect())
[ada:30 bob:10]
func Union[T comparable](a, b Seq[T]) Seq[T]

Union yields the distinct elements of a, then the distinct elements of b not in a — set semantics, encounter order.

// Set semantics: the result is deduplicated, in encounter order,
// left operand first.
fmt.Println(catena.Union(catena.Of(1, 2, 2), catena.Of(3, 1)).Collect())
[1 2 3]
func Intersect[T comparable](a, b Seq[T]) Seq[T]

Intersect yields the distinct elements of a that occur in b, in a’s encounter order.

fmt.Println(catena.Intersect(catena.Of(1, 2, 3), catena.Of(3, 1)).Collect())
[1 3]
func Except[T comparable](a, b Seq[T]) Seq[T]

Except yields the distinct elements of a that do not occur in b, in a’s encounter order.

fmt.Println(catena.Except(catena.Of(1, 2, 3), catena.Of(2)).Collect())
[1 3]
func (s Seq[T]) Intersperse(sep T) Seq[T]

Intersperse yields sep between consecutive elements.

fmt.Println(catena.Of("a", "b", "c").Intersperse("-").Collect())
[a - b - c]
func (s Seq[T]) IfEmpty(defaults ...T) Seq[T]

IfEmpty yields s, or the given defaults if s yields nothing.

// A fallback for the whole sequence, not per element.
fmt.Println(catena.Of(1, 2).IfEmpty(0).Collect())
fmt.Println(catena.Empty[int]().IfEmpty(0).Collect())
[1 2]
[0]