go2linq

package module
v2.10.0 Latest Latest
Warning

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

Go to latest
Published: Jun 7, 2023 License: MIT Imports: 11 Imported by: 0

README

go2linq

Go Reference

go2linq is Go implementation of .NET's LINQ to Objects. (See also: Language Integrated Query, LINQ, Enumerable Class.)

go2linq was initially inspired by Jon Skeet's Edulinq series.


Installation

go get github.com/solsw/go2linq/v2

Examples

Examples of go2linq usage are in the Example... functions in test files (see Examples).

Quick and easy example:
package main

import (
	"fmt"

	"github.com/solsw/go2linq/v2"
)

func main() {
	filter := go2linq.WhereMust(
		go2linq.NewEnSliceEn(1, 2, 3, 4, 5, 6, 7, 8),
		func(i int) bool { return i > 6 || i%2 == 0 },
	)
	squares := go2linq.SelectMust(
		filter,
		func(i int) string { return fmt.Sprintf("%d: %d", i, i*i) },
	)
	enr := squares.GetEnumerator()
	for enr.MoveNext() {
		square := enr.Current()
		fmt.Println(square)
	}
}

The previous code outputs the following:

2: 4
4: 16
6: 36
7: 49
8: 64

Documentation

Overview

Package go2linq implements .NET's LINQ to Objects.

See also:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrDuplicateKeys    = errors.New("duplicate keys")
	ErrEmptySource      = errors.New("empty source")
	ErrIndexOutOfRange  = errors.New("index out of range")
	ErrMultipleElements = errors.New("multiple elements")
	ErrMultipleMatch    = errors.New("multiple match")
	ErrNegativeCount    = errors.New("negative count")
	ErrNilAccumulator   = errors.New("nil accumulator")
	ErrNilAction        = errors.New("nil action")
	ErrNilComparer      = errors.New("nil comparer")
	ErrNilLesser        = errors.New("nil lesser")
	ErrNilPredicate     = errors.New("nil predicate")
	ErrNilSelector      = errors.New("nil selector")
	ErrNilSource        = errors.New("nil source")
	ErrNoMatch          = errors.New("no match")
	ErrSizeOutOfRange   = errors.New("size out of range")
)

Functions

func Aggregate

func Aggregate[Source any](source Enumerable[Source], accumulator func(Source, Source) Source) (Source, error)

Aggregate applies an accumulator function over a sequence.

func AggregateMust

func AggregateMust[Source any](source Enumerable[Source], accumulator func(Source, Source) Source) Source

AggregateMust is like Aggregate but panics in case of error.

Example

see the last example from Enumerable.Aggregate help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.aggregate

sentence := "the quick brown fox jumps over the lazy dog"
// Split the string into individual words.
words := strings.Fields(sentence)
// Prepend each word to the beginning of the new sentence to reverse the word order.
reversed := AggregateMust(
	NewEnSliceEn(words...),
	func(workingSentence, next string) string { return next + " " + workingSentence },
)
fmt.Println(reversed)
Output:

dog lazy the over jumps fox brown quick the

func AggregateSeed

func AggregateSeed[Source, Accumulate any](source Enumerable[Source],
	seed Accumulate, accumulator func(Accumulate, Source) Accumulate) (Accumulate, error)

AggregateSeed applies an accumulator function over a sequence.

The specified seed value is used as the initial accumulator value.

func AggregateSeedMust

func AggregateSeedMust[Source, Accumulate any](source Enumerable[Source],
	seed Accumulate, accumulator func(Accumulate, Source) Accumulate) Accumulate

AggregateSeedMust is like AggregateSeed but panics in case of error.

Example

see the second example from Enumerable.Aggregate help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.aggregate

ints := []int{4, 8, 8, 3, 9, 0, 7, 8, 2}
// Count the even numbers in the array, using a seed value of 0.
numEven := AggregateSeedMust(
	NewEnSliceEn(ints...),
	0,
	func(total, next int) int {
		if next%2 == 0 {
			return total + 1
		}
		return total
	},
)
fmt.Printf("The number of even integers is: %d\n", numEven)
Output:

The number of even integers is: 6

func AggregateSeedSel

func AggregateSeedSel[Source, Accumulate, Result any](source Enumerable[Source], seed Accumulate,
	accumulator func(Accumulate, Source) Accumulate, resultSelector func(Accumulate) Result) (Result, error)

AggregateSeedSel applies an accumulator function over a sequence.

The specified seed value is used as the initial accumulator value, and the specified function is used to select the result value.

func AggregateSeedSelMust

func AggregateSeedSelMust[Source, Accumulate, Result any](source Enumerable[Source], seed Accumulate,
	accumulator func(Accumulate, Source) Accumulate, resultSelector func(Accumulate) Result) Result

AggregateSeedSelMust is like AggregateSeedSel but panics in case of error.

Example

see the first example from Enumerable.Aggregate help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.aggregate

fruits := []string{"apple", "mango", "orange", "passionfruit", "grape"}
// Determine whether any string in the array is longer than "banana".
longestName := AggregateSeedSelMust(
	NewEnSliceEn(fruits...),
	"banana",
	func(longest, next string) string {
		if len(next) > len(longest) {
			return next
		}
		return longest
	},
	// Return the final result as an upper case string.
	func(fruit string) string { return strings.ToUpper(fruit) },
)
fmt.Printf("The fruit with the longest name is %s.\n", longestName)
Output:

The fruit with the longest name is PASSIONFRUIT.

func All

func All[Source any](source Enumerable[Source], predicate func(Source) bool) (bool, error)

All determines whether all elements of a sequence satisfy a condition.

func AllMust

func AllMust[Source any](source Enumerable[Source], predicate func(Source) bool) bool

AllMust is like All but panics in case of error.

Example (Ex1)

see AllEx example from Enumerable.All help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.all#examples

pets := []Pet{
	{Name: "Barley", Age: 10},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 6},
}
// Determine whether all Pet names in the array start with 'B'.
allStartWithB := AllMust(
	NewEnSliceEn(pets...),
	func(pet Pet) bool { return strings.HasPrefix(pet.Name, "B") },
)
var what string
if allStartWithB {
	what = "All"
} else {
	what = "Not all"
}
fmt.Printf("%s pet names start with 'B'.\n", what)
Output:

Not all pet names start with 'B'.
Example (Ex2)

see AllEx2 example from Enumerable.All help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.all#examples

people := []Person{
	{
		LastName: "Haas",
		Pets: []Pet{
			{Name: "Barley", Age: 10},
			{Name: "Boots", Age: 14},
			{Name: "Whiskers", Age: 6},
		},
	},
	{
		LastName: "Fakhouri",
		Pets: []Pet{
			{Name: "Snowball", Age: 1},
		},
	},
	{
		LastName: "Antebi",
		Pets: []Pet{
			{Name: "Belle", Age: 8},
		},
	},
	{
		LastName: "Philips",
		Pets: []Pet{
			{Name: "Sweetie", Age: 2},
			{Name: "Rover", Age: 13},
		},
	},
}
// Determine which people have Pets that are all older than 5.
where := WhereMust(
	NewEnSliceEn(people...),
	func(person Person) bool {
		return AllMust(NewEnSliceEn(person.Pets...), func(pet Pet) bool { return pet.Age > 5 })
	},
)
names := SelectMust(
	where,
	func(person Person) string { return person.LastName },
)
enr := names.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Println(name)
}
Output:

Haas
Antebi
Example (Ex3)

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#query-expression-syntax-examples https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#all

markets := []Market{
	{Name: "Emily's", Items: []string{"kiwi", "cheery", "banana"}},
	{Name: "Kim's", Items: []string{"melon", "mango", "olive"}},
	{Name: "Adam's", Items: []string{"kiwi", "apple", "orange"}},
}
where := WhereMust(
	NewEnSliceEn(markets...),
	func(m Market) bool {
		return AllMust(NewEnSliceEn(m.Items...), func(item string) bool { return len(item) == 5 })
	},
)
names := SelectMust(where, func(m Market) string { return m.Name })
enr := names.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Printf("%s market\n", name)
}
Output:

Kim's market

func Any

func Any[Source any](source Enumerable[Source]) (bool, error)

Any determines whether a sequence contains any elements.

func AnyMust

func AnyMust[Source any](source Enumerable[Source]) bool

AnyMust is like Any but panics in case of error.

Example (Ex1)

see the first example from Enumerable.Any help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.any

numbers := []int{1, 2}
hasElements := AnyMust(NewEnSliceEn(numbers...))
var what string
if hasElements {
	what = "is not"
} else {
	what = "is"
}
fmt.Printf("The list %s empty.\n", what)
Output:

The list is not empty.
Example (Ex2)

see AnyEx2 example from Enumerable.Any help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.any

people := []Person{
	{
		LastName: "Haas",
		Pets: []Pet{
			{Name: "Barley", Age: 10},
			{Name: "Boots", Age: 14},
			{Name: "Whiskers", Age: 6},
		},
	},
	{
		LastName: "Fakhouri",
		Pets: []Pet{
			{Name: "Snowball", Age: 1},
		},
	},
	{
		LastName: "Antebi",
		Pets:     []Pet{},
	},
	{
		LastName: "Philips",
		Pets: []Pet{
			{Name: "Sweetie", Age: 2},
			{Name: "Rover", Age: 13},
		},
	},
}
// Determine which people have a non-empty Pet array.
where := WhereMust(
	NewEnSliceEn(people...),
	func(person Person) bool { return AnyMust(NewEnSliceEn(person.Pets...)) },
)
names := SelectMust(
	where,
	func(person Person) string { return person.LastName },
)
enr := names.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Println(name)
}
Output:

Haas
Fakhouri
Philips

func AnyPred

func AnyPred[Source any](source Enumerable[Source], predicate func(Source) bool) (bool, error)

AnyPred determines whether any element of a sequence satisfies a condition.

func AnyPredMust

func AnyPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) bool

AnyPredMust is like AnyPred but panics in case of error.

Example (Ex1)

see AnyEx3 example from Enumerable.Any help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.any

pets := []Pet{
	{Name: "Barley", Age: 8, Vaccinated: true},
	{Name: "Boots", Age: 4, Vaccinated: false},
	{Name: "Whiskers", Age: 1, Vaccinated: false},
}
// Determine whether any pets over Age 1 are also unvaccinated.
unvaccinated := AnyPredMust(
	NewEnSliceEn(pets...),
	func(pet Pet) bool { return pet.Age > 1 && pet.Vaccinated == false },
)
var what string
if unvaccinated {
	what = "are"
} else {
	what = "are not any"
}
fmt.Printf("There %s unvaccinated animals over age one.\n", what)
Output:

There are unvaccinated animals over age one.
Example (Ex2)

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#query-expression-syntax-examples https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#any

markets := []Market{
	{Name: "Emily's", Items: []string{"kiwi", "cheery", "banana"}},
	{Name: "Kim's", Items: []string{"melon", "mango", "olive"}},
	{Name: "Adam's", Items: []string{"kiwi", "apple", "orange"}},
}
where := WhereMust(
	NewEnSliceEn(markets...),
	func(m Market) bool {
		return AnyPredMust(
			NewEnSliceEn(m.Items...),
			func(item string) bool { return strings.HasPrefix(item, "o") },
		)
	},
)
names := SelectMust(where, func(m Market) string { return m.Name })
enr := names.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Printf("%s market\n", name)
}
Output:

Kim's market
Adam's market

func Average

func Average[Source constraints.Integer | constraints.Float](source Enumerable[Source]) (float64, error)

Average computes the average of a sequence of constraints.Integer or constraints.Float values.

func AverageMust

func AverageMust[Source constraints.Integer | constraints.Float](source Enumerable[Source]) float64

AverageMust is like Average but panics in case of error.

Example (Ex1)

see the example from Enumerable.Average help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.average

grades := []int{78, 92, 100, 37, 81}
average := AverageMust(
	NewEnSliceEn(grades...),
)
fmt.Printf("The average grade is %g.\n", average)
Output:

The average grade is 77.6.
Example (Ex2)

see the example from Enumerable.Average help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.average

numbers := []string{"10007", "37", "299846234235"}
average := AverageSelMust(
	NewEnSliceEn(numbers...),
	func(e string) int {
		r, _ := strconv.Atoi(e)
		return r
	},
)
fmt.Printf("The average is %.f.\n", average)
Output:

The average is 99948748093.

func AverageSel

func AverageSel[Source any, Result constraints.Integer | constraints.Float](source Enumerable[Source],
	selector func(Source) Result) (float64, error)

AverageSel computes the average of a sequence of constraints.Integer or constraints.Float values that are obtained by invoking a transform function on each element of the input sequence.

func AverageSelMust

func AverageSelMust[Source any, Result constraints.Integer | constraints.Float](source Enumerable[Source],
	selector func(Source) Result) float64

AverageSelMust is like AverageSel but panics in case of error.

Example

see the example from Enumerable.Average help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.average

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
average := AverageSelMust(
	NewEnSliceEn(fruits...),
	func(e string) int { return len(e) },
)
fmt.Printf("The average string length is %g.\n", average)
Output:

The average string length is 6.5.

func Contains

func Contains[Source any](source Enumerable[Source], value Source) (bool, error)

Contains determines whether a sequence contains a specified element using collate.DeepEqualer.

func ContainsEq

func ContainsEq[Source any](source Enumerable[Source], value Source, equaler collate.Equaler[Source]) (bool, error)

ContainsEq determines whether a sequence contains a specified element using a specified equaler. If 'equaler' is nil collate.DeepEqualer is used.

func ContainsEqMust

func ContainsEqMust[Source any](source Enumerable[Source], value Source, equaler collate.Equaler[Source]) bool

ContainsEqMust is like ContainsEq but panics in case of error.

Example

see the second example from Enumerable.Contains help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.contains

fruits := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
	{Name: "lemon", Code: 12},
}
apple := Product{Name: "apple", Code: 9}
kiwi := Product{Name: "kiwi", Code: 8}
var equaler collate.Equaler[Product] = collate.EqualerFunc[Product](
	func(p1, p2 Product) bool {
		return p1.Code == p2.Code && p1.Name == p2.Name
	},
)
hasApple := ContainsEqMust(NewEnSliceEn(fruits...), apple, equaler)
hasKiwi := ContainsEqMust(NewEnSliceEn(fruits...), kiwi, equaler)
fmt.Printf("Apple? %t\n", hasApple)
fmt.Printf("Kiwi? %t\n", hasKiwi)
Output:

Apple? true
Kiwi? false

func ContainsMust

func ContainsMust[Source any](source Enumerable[Source], value Source) bool

ContainsMust is like Contains but panics in case of error.

Example (Ex1)

see the first example from Enumerable.Contains help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.contains

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
fruit := "mango"
hasMango := ContainsMust(NewEnSliceEn(fruits...), fruit)
var what string
if hasMango {
	what = "does"
} else {
	what = "does not"
}
fmt.Printf("The array %s contain '%s'.\n", what, fruit)
Output:

The array does contain 'mango'.
Example (Ex2)

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#query-expression-syntax-examples https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/quantifier-operations#contains

markets := []Market{
	{Name: "Emily's", Items: []string{"kiwi", "cheery", "banana"}},
	{Name: "Kim's", Items: []string{"melon", "mango", "olive"}},
	{Name: "Adam's", Items: []string{"kiwi", "apple", "orange"}},
}
where := WhereMust(
	NewEnSliceEn(markets...),
	func(m Market) bool {
		return ContainsMust(NewEnSliceEn(m.Items...), "kiwi")
	},
)
names := SelectMust(where, func(m Market) string { return m.Name })
enr := names.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Printf("%s market\n", name)
}
Output:

Emily's market
Adam's market

func Count

func Count[Source any](source Enumerable[Source]) (int, error)

Count returns the number of elements in a sequence.

func CountMust

func CountMust[Source any](source Enumerable[Source]) int

CountMust is like Count but panics in case of error.

Example

see the first example from Enumerable.Count help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.count

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
numberOfFruits := CountMust(NewEnSliceEn(fruits...))
fmt.Printf("There are %d fruits in the collection.\n", numberOfFruits)
Output:

There are 6 fruits in the collection.

func CountPred

func CountPred[Source any](source Enumerable[Source], predicate func(Source) bool) (int, error)

CountPred returns a number that represents how many elements in a specified sequence satisfy a condition.

func CountPredMust

func CountPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) int

CountPredMust is like CountPred but panics in case of error.

Example (Ex1)

see CountEx2 example from Enumerable.Count help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.count

pets := []Pet{
	{Name: "Barley", Vaccinated: true},
	{Name: "Boots", Vaccinated: false},
	{Name: "Whiskers", Vaccinated: false},
}
numberUnvaccinated := CountPredMust(
	NewEnSliceEn(pets...),
	func(p Pet) bool { return p.Vaccinated == false },
)
fmt.Printf("There are %d unvaccinated animals.\n", numberUnvaccinated)
Output:

There are 2 unvaccinated animals.
Example (Ex2)

see LongCountEx2 example from Enumerable.LongCount help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.longcount

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
const Age = 3
count := CountPredMust(
	NewEnSliceEn(pets...),
	func(pet Pet) bool { return pet.Age > Age },
)
fmt.Printf("There are %d animals over age %d.\n", count, Age)
Output:

There are 2 animals over age 3.

func ElementAt

func ElementAt[Source any](source Enumerable[Source], index int) (Source, error)

ElementAt returns the element at a specified index in a sequence.

func ElementAtMust

func ElementAtMust[Source any](source Enumerable[Source], index int) Source

ElementAtMust is like ElementAt but panics in case of error.

Example

see the example from Enumerable.ElementAt help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.elementat

names := []string{"Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow", "Hedlund, Magnus", "Ito, Shu"}
rand.Seed(623)
name := ElementAtMust(
	NewEnSliceEn(names...),
	rand.Intn(CountMust(NewEnSliceEn(names...))),
)
fmt.Printf("The name chosen at random is '%s'.\n", name)
Output:

The name chosen at random is 'Hedlund, Magnus'.

func ElementAtOrDefault

func ElementAtOrDefault[Source any](source Enumerable[Source], index int) (Source, error)

ElementAtOrDefault returns the element at a specified index in a sequence or a zero value if the index is out of range.

func ElementAtOrDefaultMust

func ElementAtOrDefaultMust[Source any](source Enumerable[Source], index int) Source

ElementAtOrDefaultMust is like ElementAtOrDefault but panics in case of error.

Example

see the example from Enumerable.ElementAtOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.elementatordefault

names := []string{"Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow", "Hedlund, Magnus", "Ito, Shu"}
index := 20
name := ElementAtOrDefaultMust(NewEnSliceEn(names...), index)
var what string
if name == "" {
	what = "<no name at this index>"
} else {
	what = name
}
fmt.Printf("The name chosen at index %d is '%s'.\n", index, what)
Output:

The name chosen at index 20 is '<no name at this index>'.

func First

func First[Source any](source Enumerable[Source]) (Source, error)

First returns the first element of a sequence.

func FirstMust

func FirstMust[Source any](source Enumerable[Source]) Source

FirstMust is like First but panics in case of error.

Example

see the second example from Enumerable.First help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.first

numbers := []int{9, 34, 65, 92, 87, 435, 3, 54, 83, 23, 87, 435, 67, 12, 19}
first := FirstMust(NewEnSliceEn(numbers...))
fmt.Println(first)
Output:

9

func FirstOrDefault

func FirstOrDefault[Source any](source Enumerable[Source]) (Source, error)

FirstOrDefault returns the first element of a sequence, or a zero value if the sequence contains no elements.

func FirstOrDefaultMust

func FirstOrDefaultMust[Source any](source Enumerable[Source]) Source

FirstOrDefaultMust is like FirstOrDefault but panics in case of error.

Example

see the first two examples from Enumerable.FirstOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.firstordefault

numbers := []int{}
firstOrDefault := FirstOrDefaultMust(NewEnSliceEn(numbers...))
fmt.Println(firstOrDefault)

months := []int{}
// Setting the default value to 1 after the query.
firstOrDefault1 := FirstOrDefaultMust(NewEnSliceEn(months...))
if firstOrDefault1 == 0 {
	firstOrDefault1 = 1
}
fmt.Printf("The value of the firstMonth1 variable is %v\n", firstOrDefault1)

// Setting the default value to 1 by using DefaultIfEmptyDef() in the query.
firstOrDefault2 := FirstMust(DefaultIfEmptyDefMust(NewEnSliceEn(months...), 1))
fmt.Printf("The value of the firstMonth2 variable is %v\n", firstOrDefault2)
Output:

0
The value of the firstMonth1 variable is 1
The value of the firstMonth2 variable is 1

func FirstOrDefaultPred

func FirstOrDefaultPred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

FirstOrDefaultPred returns the first element of the sequence that satisfies a condition or a zero value if no such element is found.

func FirstOrDefaultPredMust

func FirstOrDefaultPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

FirstOrDefaultPredMust is like FirstOrDefaultPred but panics in case of error.

Example

see the last example from Enumerable.FirstOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.firstordefault

names := []string{"Hartono, Tommy", "Adams, Terry", "Andersen, Henriette Thaulow", "Hedlund, Magnus", "Ito, Shu"}
firstLongName := FirstOrDefaultPredMust(
	NewEnSliceEn(names...),
	func(name string) bool { return len(name) > 20 },
)
fmt.Printf("The first long name is '%v'.\n", firstLongName)

firstVeryLongName := FirstOrDefaultPredMust(
	NewEnSliceEn(names...),
	func(name string) bool { return len(name) > 30 },
)
var what string
if firstVeryLongName == "" {
	what = "not a"
} else {
	what = "a"
}
fmt.Printf("There is %v name longer than 30 characters.\n", what)
Output:

The first long name is 'Andersen, Henriette Thaulow'.
There is not a name longer than 30 characters.

func FirstPred

func FirstPred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

FirstPred returns the first element in a sequence that satisfies a specified condition.

func FirstPredMust

func FirstPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

FirstPredMust is like FirstPred but panics in case of error.

Example

see the first example from Enumerable.First help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.first

numbers := []int{9, 34, 65, 92, 87, 435, 3, 54, 83, 23, 87, 435, 67, 12, 19}
firstPred := FirstPredMust(
	NewEnSliceEn(numbers...),
	func(number int) bool { return number > 80 },
)
fmt.Println(firstPred)
Output:

92

func ForEach

func ForEach[T any](ctx context.Context, en Enumerable[T], action func(T) error) error

ForEach sequentially performs a specified 'action' on each element of the sequence starting from the current.

If 'ctx' is canceled or 'action' returns non-nil error, the operation is canceled and corresponding error is returned.

func ForEachConcurrent

func ForEachConcurrent[T any](ctx context.Context, en Enumerable[T], action func(T) error) error

ForEachConcurrent concurrently performs a specified 'action' on each element of the sequence starting from the current.

If 'ctx' is canceled or 'action' returns non-nil error, the operation is canceled and corresponding error is returned.

func Identity

func Identity[T any](el T) T

Identity is a selector that projects the element into itself.

func Last

func Last[Source any](source Enumerable[Source]) (Source, error)

Last returns the last element of a sequence.

func LastMust

func LastMust[Source any](source Enumerable[Source]) Source

LastMust is like Last but panics in case of error.

Example

see the first example from Enumerable.Last help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.last

numbers := []int{9, 34, 65, 92, 87, 435, 3, 54, 83, 23, 87, 67, 12, 19}
last := LastMust(
	NewEnSliceEn(numbers...),
)
fmt.Println(last)
Output:

19

func LastOrDefault

func LastOrDefault[Source any](source Enumerable[Source]) (Source, error)

LastOrDefault returns the last element of a sequence or a zero value if the sequence contains no elements.

func LastOrDefaultMust

func LastOrDefaultMust[Source any](source Enumerable[Source]) Source

LastOrDefaultMust is like LastOrDefault but panics in case of error.

Example

see the first two examples from Enumerable.LastOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.lastordefault

fruits := []string{}
last := LastOrDefaultMust(
	NewEnSliceEn(fruits...),
)
if last == "" {
	fmt.Println("<string is empty>")
} else {
	fmt.Println(last)
}

daysOfMonth := []int{}
// Setting the default value to 1 after the query.
lastDay1 := LastOrDefaultMust(
	NewEnSliceEn(daysOfMonth...),
)
if lastDay1 == 0 {
	lastDay1 = 1
}
fmt.Printf("The value of the lastDay1 variable is %v\n", lastDay1)

// Setting the default value to 1 by using DefaultIfEmptyDef() in the query.
lastDay2 := LastMust(
	DefaultIfEmptyDefMust(
		NewEnSliceEn(daysOfMonth...),
		1,
	),
)
fmt.Printf("The value of the lastDay2 variable is %d\n", lastDay2)
Output:

<string is empty>
The value of the lastDay1 variable is 1
The value of the lastDay2 variable is 1

func LastOrDefaultPred

func LastOrDefaultPred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

LastOrDefaultPred returns the last element of a sequence that satisfies a condition or a zero value if no such element is found.

func LastOrDefaultPredMust

func LastOrDefaultPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

LastOrDefaultPredMust is like LastOrDefaultPred but panics in case of error.

Example

see the last example from Enumerable.LastOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.lastordefault

numbers := []float64{49.6, 52.3, 51.0, 49.4, 50.2, 48.3}
last50 := LastOrDefaultPredMust(
	NewEnSliceEn(numbers...),
	func(n float64) bool { return math.Round(n) == 50.0 },
)
fmt.Printf("The last number that rounds to 50 is %v.\n", last50)

last40 := LastOrDefaultPredMust(
	NewEnSliceEn(numbers...),
	func(n float64) bool { return math.Round(n) == 40.0 },
)
var what string
if last40 == 0.0 {
	what = "<DOES NOT EXIST>"
} else {
	what = fmt.Sprint(last40)
}
fmt.Printf("The last number that rounds to 40 is %v.\n", what)
Output:

The last number that rounds to 50 is 50.2.
The last number that rounds to 40 is <DOES NOT EXIST>.

func LastPred

func LastPred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

LastPred returns the last element of a sequence that satisfies a specified condition.

func LastPredMust

func LastPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

LastPredMust is like LastPred but panics in case of error.

Example

see the last example from Enumerable.Last help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.last

numbers := []int{9, 34, 65, 92, 87, 435, 3, 54, 83, 23, 87, 67, 12, 19}
lastPred := LastPredMust(
	NewEnSliceEn(numbers...),
	func(number int) bool { return number > 80 },
)
fmt.Println(lastPred)
Output:

87

func Max

func Max[Source constraints.Ordered](source Enumerable[Source]) (Source, error)

Max returns the maximum value in a sequence.

func MaxBySel

func MaxBySel[Source any, Key constraints.Ordered](source Enumerable[Source], selector func(Source) Key) (Source, error)

MaxBySel returns the value in a sequence that produces the maximum key according to a key selector function.

func MaxBySelLs

func MaxBySelLs[Source, Key any](source Enumerable[Source], selector func(Source) Key, lesser collate.Lesser[Key]) (Source, error)

MaxBySelLs returns the value in a sequence that produces the maximum key according to a key selector function and a key lesser.

func MaxBySelLsMust

func MaxBySelLsMust[Source, Key any](source Enumerable[Source], selector func(Source) Key, lesser collate.Lesser[Key]) Source

MaxBySelLsMust is like MaxBySelLs but panics in case of error.

func MaxBySelMust

func MaxBySelMust[Source any, Key constraints.Ordered](source Enumerable[Source], selector func(Source) Key) Source

MaxBySelMust is like MaxBySel but panics in case of error.

Example
fmt.Println(
	MaxBySelMust(
		RangeMust(1, 10),
		func(i int) int { return i * i % 10 },
	),
)
fmt.Println(
	MaxBySelMust(
		NewEnSliceEn("one", "two", "three", "four", "five"),
		func(s string) int { return len(s) },
	),
)
Output:

3
three

func MaxLs

func MaxLs[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) (Source, error)

MaxLs returns the maximum value in a sequence using a specified lesser.

func MaxLsMust

func MaxLsMust[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) Source

MaxLsMust is like MaxLs but panics in case of error.

Example

see MaxEx3 example from Enumerable.Max help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.max

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
maxLs := MaxLsMust(
	NewEnSliceEn(pets...),
	// Compares Pets by summing each Pet's age and name length.
	collate.Lesser[Pet](
		collate.LesserFunc[Pet](
			func(p1, p2 Pet) bool { return p1.Age+len(p1.Name) < p2.Age+len(p2.Name) },
		),
	),
)
fmt.Printf("The 'maximum' animal is %s.\n", maxLs.Name)
Output:

The 'maximum' animal is Barley.

func MaxMust

func MaxMust[Source constraints.Ordered](source Enumerable[Source]) Source

MaxMust is like Max but panics in case of error.

Example

see the first example from Enumerable.Max help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.max

longs := []int{4294967296, 466855135, 81125}
max := MaxMust(
	NewEnSliceEn(longs...),
)
fmt.Printf("The largest number is %d.\n", max)
Output:

The largest number is 4294967296.

func MaxSel

func MaxSel[Source any, Result constraints.Ordered](source Enumerable[Source], selector func(Source) Result) (Result, error)

MaxSel invokes a transform function on each element of a sequence and returns the maximum resulting value.

func MaxSelLs

func MaxSelLs[Source, Result any](source Enumerable[Source], selector func(Source) Result, lesser collate.Lesser[Result]) (Result, error)

MaxSelLs invokes a transform function on each element of a sequence and returns the maximum resulting value using a specified lesser.

func MaxSelLsMust

func MaxSelLsMust[Source, Result any](source Enumerable[Source], selector func(Source) Result, lesser collate.Lesser[Result]) Result

MaxSelLsMust is like MaxSelLs but panics in case of error.

func MaxSelMust

func MaxSelMust[Source any, Result constraints.Ordered](source Enumerable[Source], selector func(Source) Result) Result

MaxSelMust is like MaxSel but panics in case of error.

Example

see MaxEx4 example from Enumerable.Max help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.max

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
maxSel := MaxSelMust(
	NewEnSliceEn(pets...),
	func(pet Pet) int { return pet.Age + len(pet.Name) },
)
fmt.Printf("The maximum pet age plus name length is %d.\n", maxSel)
Output:

The maximum pet age plus name length is 14.

func Min

func Min[Source constraints.Ordered](source Enumerable[Source]) (Source, error)

Min returns the minimum value in a sequence.

func MinBySel

func MinBySel[Source any, Key constraints.Ordered](source Enumerable[Source], selector func(Source) Key) (Source, error)

MinBySel returns the value in a sequence that produces the minimum key according to a key selector function.

func MinBySelLs

func MinBySelLs[Source, Key any](source Enumerable[Source], selector func(Source) Key, lesser collate.Lesser[Key]) (Source, error)

MinBySelLs returns the value in a sequence that produces the minimum key according to a key selector function and a key lesser.

func MinBySelLsMust

func MinBySelLsMust[Source, Key any](source Enumerable[Source], selector func(Source) Key, lesser collate.Lesser[Key]) Source

MinBySelLsMust is like MinBySelLs but panics in case of error.

func MinBySelMust

func MinBySelMust[Source any, Key constraints.Ordered](source Enumerable[Source], selector func(Source) Key) Source

MinBySelMust is like MinBySel but panics in case of error.

Example
fmt.Println(
	MinBySelMust(
		RangeMust(1, 10),
		func(i int) int { return i * i % 10 },
	),
)
fmt.Println(
	MinBySelMust(
		NewEnSliceEn("one", "two", "three", "four", "five"),
		func(s string) int { return len(s) },
	),
)
Output:

10
one

func MinLs

func MinLs[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) (Source, error)

MinLs returns the minimum value in a sequence using a specified lesser.

func MinLsMust

func MinLsMust[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) Source

MinLsMust is like MinLs but panics in case of error.

Example

see MinEx3 example from Enumerable.Min help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.min

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
minLs := MinLsMust(
	NewEnSliceEn(pets...),
	// Compares Pet's ages.
	collate.Lesser[Pet](collate.LesserFunc[Pet](
		func(p1, p2 Pet) bool { return p1.Age < p2.Age },
	)),
)
fmt.Printf("The 'minimum' animal is %s.\n", minLs.Name)
Output:

The 'minimum' animal is Whiskers.

func MinMust

func MinMust[Source constraints.Ordered](source Enumerable[Source]) Source

MinMust is like Min but panics in case of error.

Example

see the first example from Enumerable.Min help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.min

doubles := []float64{1.5e+104, 9e+103, -2e+103}
min := MinMust(
	NewEnSliceEn(doubles...),
)
fmt.Printf("The smallest number is %G.\n", min)
Output:

The smallest number is -2E+103.

func MinSel

func MinSel[Source any, Result constraints.Ordered](source Enumerable[Source], selector func(Source) Result) (Result, error)

MinSel invokes a transform function on each element of a sequence and returns the minimum resulting value.

func MinSelLs

func MinSelLs[Source, Result any](source Enumerable[Source], selector func(Source) Result, lesser collate.Lesser[Result]) (Result, error)

MinSelLs invokes a transform function on each element of a sequence and returns the minimum resulting value using a specified lesser.

func MinSelLsMust

func MinSelLsMust[Source, Result any](source Enumerable[Source], selector func(Source) Result, lesser collate.Lesser[Result]) Result

MinSelLsMust is like MinSelLs but panics in case of error.

func MinSelMust

func MinSelMust[Source any, Result constraints.Ordered](source Enumerable[Source], selector func(Source) Result) Result

MinSelMust is like MinSel but panics in case of error.

Example

see MinEx4 example from Enumerable.Min help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.min

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
minSel := MinSelMust(
	NewEnSliceEn(pets...),
	func(pet Pet) int { return pet.Age },
)
fmt.Printf("The youngest animal is age %d.\n", minSel)
Output:

The youngest animal is age 1.

func SequenceEqual

func SequenceEqual[Source any](first, second Enumerable[Source]) (bool, error)

SequenceEqual determines whether two sequences are equal by comparing the elements using collate.DeepEqualer.

func SequenceEqualEq

func SequenceEqualEq[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) (bool, error)

SequenceEqualEq determines whether two sequences are equal by comparing their elements using a specified equaler. If 'equaler' is nil collate.DeepEqualer is used.

func SequenceEqualEqMust

func SequenceEqualEqMust[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) bool

SequenceEqualEqMust is like SequenceEqualEq but panics in case of error.

Example

see the last example from Enumerable.SequenceEqual help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.sequenceequal

storeA := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
}
storeB := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
}
equalEq := SequenceEqualEqMust(
	NewEnSliceEn(storeA...),
	NewEnSliceEn(storeB...),
	collate.Equaler[Product](
		collate.EqualerFunc[Product](
			func(p1, p2 Product) bool {
				return p1.Code == p2.Code && p1.Name == p2.Name
			},
		),
	),
)
fmt.Printf("Equal? %t\n", equalEq)
Output:

Equal? true

func SequenceEqualMust

func SequenceEqualMust[Source any](first, second Enumerable[Source]) bool

SequenceEqualMust is like SequenceEqual but panics in case of error.

Example

see SequenceEqualEx1 example from Enumerable.SequenceEqual help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.sequenceequal

pet1 := Pet{Name: "Turbo", Age: 2}
pet2 := Pet{Name: "Peanut", Age: 8}
pets1 := []Pet{pet1, pet2}
pets2 := []Pet{pet1, pet2}
equal := SequenceEqualMust(
	NewEnSliceEn(pets1...),
	NewEnSliceEn(pets2...),
)
var what string
if equal {
	what = "are"
} else {
	what = "are not"
}
fmt.Printf("The lists %s equal.\n", what)
Output:

The lists are equal.

func Single

func Single[Source any](source Enumerable[Source]) (Source, error)

Single returns the only element of a sequence and returns an error if there is not exactly one element in the sequence.

Example

see the second example from Enumerable.Single help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.single

fruits := []string{"orange", "apple"}
fruit, err := Single(
	NewEnSliceEn(fruits...),
)
if err == ErrMultipleElements {
	fmt.Println("The collection does not contain exactly one element.")
} else {
	fmt.Println(fruit)
}
Output:

The collection does not contain exactly one element.

func SingleMust

func SingleMust[Source any](source Enumerable[Source]) Source

SingleMust is like Single but panics in case of error.

Example (Ex1)

see the first example from Enumerable.Single help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.single

fruits := []string{"orange"}
fruit := SingleMust(
	NewEnSliceEn(fruits...),
)
fmt.Println(fruit)
Output:

orange
Example (Ex2)

see the third example from Enumerable.SingleOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault

pageNumbers := []int{}
// Setting the default value to 1 by using DefaultIfEmpty() in the query.
pageNumber := SingleMust(
	DefaultIfEmptyDefMust(
		NewEnSliceEn(pageNumbers...),
		1,
	),
)
fmt.Printf("The value of the pageNumber2 variable is %d\n", pageNumber)
Output:

The value of the pageNumber2 variable is 1

func SingleOrDefault

func SingleOrDefault[Source any](source Enumerable[Source]) (Source, error)

SingleOrDefault returns the only element of a sequence or a zero value if the sequence is empty.

func SingleOrDefaultMust

func SingleOrDefaultMust[Source any](source Enumerable[Source]) Source

SingleOrDefaultMust is like SingleOrDefault but panics in case of error.

Example (Ex1)

see the first example from Enumerable.SingleOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault

fruits := []string{"orange"}
fruit := SingleOrDefaultMust(
	NewEnSliceEn(fruits...),
)
fmt.Println(fruit)
Output:

orange
Example (Ex2)

see the second example from Enumerable.SingleOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault

fruits := []string{}
fruit := SingleOrDefaultMust(
	NewEnSliceEn(fruits...),
)
var what string
if fruit == "" {
	what = "No such string!"
} else {
	what = fruit
}
fmt.Println(what)
Output:

No such string!
Example (Ex3)

see the third example from Enumerable.SingleOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault

var pageNumbers []int = nil
// Setting the default value to 1 after the query.
pageNumber := SingleOrDefaultMust(
	NewEnSliceEn(pageNumbers...),
)
if pageNumber == 0 {
	pageNumber = 1
}
fmt.Printf("The value of the pageNumber1 variable is %d\n", pageNumber)
Output:

The value of the pageNumber1 variable is 1

func SingleOrDefaultPred

func SingleOrDefaultPred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

SingleOrDefaultPred returns the only element of a sequence that satisfies a specified condition or a zero value if no such element exists.

func SingleOrDefaultPredMust

func SingleOrDefaultPredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

SingleOrDefaultPredMust is like SingleOrDefaultPred but panics in case of error.

Example

see the fourth and fifth examples from Enumerable.SingleOrDefault help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.singleordefault

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
fruit1 := SingleOrDefaultPredMust(
	NewEnSliceEn(fruits...),
	func(fr string) bool { return len(fr) > 10 },
)
fmt.Println(fruit1)

fruit2 := SingleOrDefaultPredMust(
	NewEnSliceEn(fruits...),
	func(fr string) bool { return len(fr) > 15 },
)
var what string
if fruit2 == "" {
	what = "No such string!"
} else {
	what = fruit2
}
fmt.Println(what)
Output:

passionfruit
No such string!

func SinglePred

func SinglePred[Source any](source Enumerable[Source], predicate func(Source) bool) (Source, error)

SinglePred returns the only element of a sequence that satisfies a specified condition.

Example

see the fourth example from Enumerable.Single help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.single

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}

fruit1, err := SinglePred(
	NewEnSliceEn(fruits...),
	func(fr string) bool { return len(fr) > 15 },
)
if err == ErrNoMatch {
	fmt.Println("The collection does not contain exactly one element whose length is greater than 15.")
} else {
	fmt.Println(fruit1)
}

fruit2, err := SinglePred(
	NewEnSliceEn(fruits...),
	func(fr string) bool { return len(fr) > 5 },
)
if err == ErrMultipleMatch {
	fmt.Println("The collection does not contain exactly one element whose length is greater than 5.")
} else {
	fmt.Println(fruit2)
}
Output:

The collection does not contain exactly one element whose length is greater than 15.
The collection does not contain exactly one element whose length is greater than 5.

func SinglePredMust

func SinglePredMust[Source any](source Enumerable[Source], predicate func(Source) bool) Source

SinglePredMust is like SinglePred but panics in case of error.

Example

see the third example from Enumerable.Single help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.single

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
fruit := SinglePredMust(
	NewEnSliceEn(fruits...),
	func(fr string) bool { return len(fr) > 10 },
)
fmt.Println(fruit)
Output:

passionfruit

func Sum

func Sum[Source constraints.Integer | constraints.Float](source Enumerable[Source]) (Source, error)

Sum computes the sum of a sequence of constraints.Integer or constraints.Float values.

func SumMust

func SumMust[Source constraints.Integer | constraints.Float](source Enumerable[Source]) Source

SumMust is like Sum but panics in case of error.

Example

see the example from Enumerable.Sum help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.sum

numbers := []float64{43.68, 1.25, 583.7, 6.5}
sum := SumMust(
	NewEnSliceEn(numbers...),
)
fmt.Printf("The sum of the numbers is %g.\n", sum)
Output:

The sum of the numbers is 635.13.

func SumSel

func SumSel[Source any, Result constraints.Integer | constraints.Float](source Enumerable[Source],
	selector func(Source) Result) (Result, error)

SumSel computes the sum of a sequence of constraints.Integer or constraints.Float values that are obtained by invoking a transform function on each element of the input sequence.

func SumSelMust

func SumSelMust[Source any, Result constraints.Integer | constraints.Float](source Enumerable[Source],
	selector func(Source) Result) Result

SumSelMust is like SumSel but panics in case of error.

Example

see SumEx1 example from Enumerable.Sum help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.sum

packages := []Package{
	{Company: "Coho Vineyard", Weight: 25.2},
	{Company: "Lucerne Publishing", Weight: 18.7},
	{Company: "Wingtip Toys", Weight: 6.0},
	{Company: "Adventure Works", Weight: 33.8},
}
totalWeight := SumSelMust(
	NewEnSliceEn(packages...),
	func(pkg Package) float64 { return pkg.Weight },
)
fmt.Printf("The total weight of the packages is: %.1f\n", totalWeight)
Output:

The total weight of the packages is: 83.7

func ToMap

func ToMap[Source any, Key comparable](source Enumerable[Source], keySelector func(Source) Key) (map[Key]Source, error)

ToMap creates a map from an Enumerable according to a specified key selector function.

func ToMapMust

func ToMapMust[Source any, Key comparable](source Enumerable[Source], keySelector func(Source) Key) map[Key]Source

ToMapMust is like ToMap but panics in case of error.

Example

see ToDictionaryEx1 example from Enumerable.ToDictionary help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.todictionary

packages := []Package{
	{Company: "Coho Vineyard", Weight: 25.2, TrackingNumber: 89453312},
	{Company: "Lucerne Publishing", Weight: 18.7, TrackingNumber: 89112755},
	{Company: "Wingtip Toys", Weight: 6.0, TrackingNumber: 299456122},
	{Company: "Adventure Works", Weight: 33.8, TrackingNumber: 4665518773},
}
// Create a map of Package objects, using TrackingNumber as the key.
dictionary := NewEnMapEn(
	ToMapMust(
		NewEnSliceEn(packages...),
		func(p Package) int64 { return p.TrackingNumber },
	),
)
enr := dictionary.GetEnumerator()
for enr.MoveNext() {
	ke := enr.Current()
	p := ke.Item2
	fmt.Printf("Key %d: %s, %g pounds\n", ke.Item1, p.Company, p.Weight)
}
Output:

Key 89453312: Coho Vineyard, 25.2 pounds
Key 89112755: Lucerne Publishing, 18.7 pounds
Key 299456122: Wingtip Toys, 6 pounds
Key 4665518773: Adventure Works, 33.8 pounds

func ToMapSel

func ToMapSel[Source any, Key comparable, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) (map[Key]Element, error)

ToMapSel creates a map from an Enumerable according to specified key selector and element selector functions.

Since Go's map does not support custom equaler to determine equality of the keys, LINQ's key comparer is not implemented. Similar to the keys equality functionality may be achieved using appropriate key selector. Example of custom key selector that mimics case-insensitive equaler for string keys is presented in [TestCustomSelector_string_string_int].

func ToMapSelMust

func ToMapSelMust[Source any, Key comparable, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) map[Key]Element

ToMapSelMust is like ToMapSel but panics in case of error.

func ToSlice

func ToSlice[Source any](source Enumerable[Source]) ([]Source, error)

ToSlice creates a slice from an Enumerable.

func ToSliceMust

func ToSliceMust[Source any](source Enumerable[Source]) []Source

ToSliceMust is like ToSlice but panics in case of error.

func ToStringDef

func ToStringDef[T any](en Enumerable[T]) string

ToStringDef returns string representation of a sequence using default formatting.

If 'en' is nil, empty string is returned.

func ToStringFmt

func ToStringFmt[T any](en Enumerable[T], sep, lrim, rrim, ledge, redge string) string

ToStringFmt returns string representation of a sequence:

  • if 'en' is nil, empty string is returned;
  • if 'en' or underlying Enumerator implements fmt.Stringer, it is used;
  • if 'T' implements fmt.Stringer, it is used to convert each element to string;
  • 'sep' is inserted between elements;
  • 'lrim' and 'rrim' surround each element;
  • 'ledge' and 'redge' surround the whole string.

func ToStrings

func ToStrings[T any](en Enumerable[T]) []string

ToStrings returns a sequence contents as a slice of strings.

If 'en' is nil, nil is returned.

func TryGetNonEnumeratedCount

func TryGetNonEnumeratedCount[Source any](source Enumerable[Source], count *int) (bool, error)

TryGetNonEnumeratedCount attempts to determine the number of elements in a sequence without forcing an enumeration.

func TryGetNonEnumeratedCountMust

func TryGetNonEnumeratedCountMust[Source any](source Enumerable[Source], count *int) bool

TryGetNonEnumeratedCountMust is like TryGetNonEnumeratedCount but panics in case of error.

Types

type Counter

type Counter interface {
	// Count returns the number of elements contained in the sequence.
	Count() int
}

Counter is the interface that wraps the Count method.

type EnChan added in v2.2.0

type EnChan[T any] <-chan T

EnChan is an Enumerable implementation based on a channel.

Example
package main

import (
	"fmt"
)

func chn3() chan int {
	var ch = make(chan int)
	go func() {
		ch <- 4
		ch <- 3
		ch <- 2
		ch <- 1
		ch <- 0
		close(ch)
	}()
	return ch
}

func main() {
	en1 := NewEnChanEn[int](chn3())
	en2 := SelectMust[int](en1, func(i int) int { return 12 / i })

	// panic: runtime error: integer divide by zero
	// fmt.Println(LastMust[int](en2))

	fmt.Println(
		FirstMust[int](en2),
	)
	fmt.Println(
		FirstMust[int](
			SkipMust[int](en2, 2),
		),
	)
}
Output:

3
12

func NewEnChan added in v2.2.0

func NewEnChan[T any](ch <-chan T) *EnChan[T]

NewEnChan creates a new EnChan with a specified channel as contents.

func (*EnChan[T]) GetEnumerator added in v2.2.0

func (en *EnChan[T]) GetEnumerator() Enumerator[T]

GetEnumerator implements the Enumerable interface.

type EnFunc added in v2.3.0

type EnFunc[T any] struct {
	// contains filtered or unexported fields
}

EnFunc is an Enumerable implementation based on functions corresponding to the Enumerable's methods.

func NewEnFunc added in v2.3.0

func NewEnFunc[T any](mvNxt func() bool, crrnt func() T, rst func()) *EnFunc[T]

NewEnFunc creates a new EnFunc with a specified functions as the Enumerable's methods.

func (*EnFunc[T]) GetEnumerator added in v2.3.0

func (en *EnFunc[T]) GetEnumerator() Enumerator[T]

GetEnumerator implements the Enumerable interface.

type EnMap added in v2.1.0

type EnMap[Key comparable, Element any] EnSlice[generichelper.Tuple2[Key, Element]]

EnMap is an Enumerable implementation based on a map.

func NewEnMap added in v2.1.0

func NewEnMap[Key comparable, Element any](m map[Key]Element) *EnMap[Key, Element]

NewEnMap creates a new EnMap with a specified map as contents.

func (*EnMap[Key, Element]) Count added in v2.1.0

func (en *EnMap[Key, Element]) Count() int

Count implements the Counter interface.

func (*EnMap[Key, Element]) GetEnumerator added in v2.1.0

func (en *EnMap[Key, Element]) GetEnumerator() Enumerator[generichelper.Tuple2[Key, Element]]

GetEnumerator implements the Enumerable interface.

type EnSlice

type EnSlice[T any] []T

EnSlice is an Enumerable implementation based on a slice of T.

func NewEnSlice

func NewEnSlice[T any](slice ...T) *EnSlice[T]

NewEnSlice creates a new EnSlice with a specified slice as contents.

func (*EnSlice[T]) Count

func (en *EnSlice[T]) Count() int

Count implements the Counter interface.

func (*EnSlice[T]) GetEnumerator

func (en *EnSlice[T]) GetEnumerator() Enumerator[T]

GetEnumerator implements the Enumerable interface.

func (*EnSlice[T]) Item

func (en *EnSlice[T]) Item(i int) T

Item implements the Itemer interface.

func (*EnSlice[T]) Slice

func (en *EnSlice[T]) Slice() []T

Slice implements the Slicer interface.

type Enumerable

type Enumerable[T any] interface {

	// [GetEnumerator] returns [Enumerator] that iterates through the collection.
	//
	// [GetEnumerator]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerable-1.getenumerator
	GetEnumerator() Enumerator[T]
}

Enumerable exposes the enumerator, which supports a simple iteration over a collection of a specified type.

func Append

func Append[Source any](source Enumerable[Source], element Source) (Enumerable[Source], error)

Append appends a value to the end of the sequence.

func AppendMust

func AppendMust[Source any](source Enumerable[Source], element Source) Enumerable[Source]

AppendMust is like Append but panics in case of error.

func Cast

func Cast[Source, Result any](source Enumerable[Source]) (Enumerable[Result], error)

Cast casts the elements of an Enumerable to a specified type.

func CastMust

func CastMust[Source, Result any](source Enumerable[Source]) Enumerable[Result]

CastMust is like Cast but panics in case of error.

func Chunk

func Chunk[Source any](source Enumerable[Source], size int) (Enumerable[[]Source], error)

Chunk splits the elements of a sequence into chunks of size at most 'size'.

func ChunkMust

func ChunkMust[Source any](source Enumerable[Source], size int) Enumerable[[]Source]

ChunkMust is like Chunk but panics in case of error.

Example

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/partitioning-data#example

chunkNumber := 0
enr1 := ChunkMust(RangeMust(0, 8), 3).GetEnumerator()
for enr1.MoveNext() {
	chunkNumber++
	fmt.Printf("Chunk %d:", chunkNumber)
	chunk := enr1.Current()
	enr2 := NewEnSlice(chunk...).GetEnumerator()
	for enr2.MoveNext() {
		item := enr2.Current()
		fmt.Printf(" %d", item)
	}
	fmt.Println()
}
Output:

Chunk 1: 0 1 2
Chunk 2: 3 4 5
Chunk 3: 6 7

func Concat

func Concat[Source any](first, second Enumerable[Source]) (Enumerable[Source], error)

Concat concatenates two sequences.

func ConcatMust

func ConcatMust[Source any](first, second Enumerable[Source]) Enumerable[Source]

ConcatMust is like Concat but panics in case of error.

Example

see ConcatEx1 example from Enumerable.Concat help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.concat#examples

cats := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
dogs := []Pet{
	{Name: "Bounder", Age: 3},
	{Name: "Snoopy", Age: 14},
	{Name: "Fido", Age: 9},
}
query := ConcatMust(
	SelectMust(
		NewEnSliceEn(cats...),
		func(cat Pet) string { return cat.Name },
	),
	SelectMust(
		NewEnSliceEn(dogs...),
		func(dog Pet) string { return dog.Name },
	),
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Println(name)
}
Output:

Barley
Boots
Whiskers
Bounder
Snoopy
Fido

func DefaultIfEmpty

func DefaultIfEmpty[Source any](source Enumerable[Source]) (Enumerable[Source], error)

DefaultIfEmpty returns the elements of a specified sequence or the type parameter's zero value in a singleton collection if the sequence is empty.

func DefaultIfEmptyDef

func DefaultIfEmptyDef[Source any](source Enumerable[Source], defaultValue Source) (Enumerable[Source], error)

DefaultIfEmptyDef returns the elements of a specified sequence or a specified value in a singleton collection if the sequence is empty.

func DefaultIfEmptyDefMust

func DefaultIfEmptyDefMust[Source any](source Enumerable[Source], defaultValue Source) Enumerable[Source]

DefaultIfEmptyDefMust is like DefaultIfEmptyDef but panics in case of error.

Example

see DefaultIfEmptyEx2 example from Enumerable.DefaultIfEmpty help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.defaultifempty

defaultPet := Pet{Name: "Default Pet", Age: 0}
pets1 := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
enr1 := DefaultIfEmptyDefMust(NewEnSliceEn(pets1...), defaultPet).GetEnumerator()
for enr1.MoveNext() {
	pet := enr1.Current()
	fmt.Printf("Name: %s\n", pet.Name)
}
pets2 := []Pet{}
enr2 := DefaultIfEmptyDefMust(NewEnSliceEn(pets2...), defaultPet).GetEnumerator()
for enr2.MoveNext() {
	pet := enr2.Current()
	fmt.Printf("\nName: %s\n", pet.Name)
}
Output:

Name: Barley
Name: Boots
Name: Whiskers

Name: Default Pet

func DefaultIfEmptyMust

func DefaultIfEmptyMust[Source any](source Enumerable[Source]) Enumerable[Source]

DefaultIfEmptyMust is like DefaultIfEmpty but panics in case of error.

Example (Ex1)

see the last example from Enumerable.DefaultIfEmpty help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.defaultifempty

numbers := DefaultIfEmptyMust(NewEnSliceEn([]int{}...))
enr := numbers.GetEnumerator()
for enr.MoveNext() {
	number := enr.Current()
	fmt.Println(number)
}
Output:

0
Example (Ex2)

see DefaultIfEmptyEx1 example from Enumerable.DefaultIfEmpty help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.defaultifempty

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
enr := DefaultIfEmptyMust(NewEnSliceEn(pets...)).GetEnumerator()
for enr.MoveNext() {
	pet := enr.Current()
	fmt.Println(pet.Name)
}
Output:

Barley
Boots
Whiskers

func Distinct

func Distinct[Source any](source Enumerable[Source]) (Enumerable[Source], error)

Distinct returns distinct elements from a sequence using collate.DeepEqualer to compare values. Order of elements in the result corresponds to the order of elements in 'source'.

func DistinctBy

func DistinctBy[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) (Enumerable[Source], error)

DistinctBy returns distinct elements from a sequence according to a specified key selector function and using collate.DeepEqualer to compare keys.

func DistinctByCmp

func DistinctByCmp[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) (Enumerable[Source], error)

DistinctByCmp returns distinct elements from a sequence according to a specified key selector function and using a specified comparer to compare keys. (See DistinctCmp.)

func DistinctByCmpMust

func DistinctByCmpMust[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) Enumerable[Source]

DistinctByCmpMust is like DistinctByCmp but panics in case of error.

func DistinctByEq

func DistinctByEq[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) (Enumerable[Source], error)

DistinctByEq returns distinct elements from a sequence according to a specified key selector function and using a specified equaler to compare keys. If 'equaler' is nil collate.DeepEqualer is used.

func DistinctByEqMust

func DistinctByEqMust[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) Enumerable[Source]

DistinctByEqMust is like DistinctByEq but panics in case of error.

func DistinctByMust

func DistinctByMust[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) Enumerable[Source]

DistinctByMust is like DistinctBy but panics in case of error.

func DistinctCmp

func DistinctCmp[Source any](source Enumerable[Source], comparer collate.Comparer[Source]) (Enumerable[Source], error)

DistinctCmp returns distinct elements from a sequence using a specified comparer to compare values. Order of elements in the result corresponds to the order of elements in 'source'.

Sorted slice of already seen elements is internally built. Sorted slice allows to use binary search to determine whether the element was seen or not. This may give performance gain when processing large sequences (though this is a subject for benchmarking, see [BenchmarkDistinctEqMust] and [BenchmarkDistinctCmpMust]).

func DistinctCmpMust

func DistinctCmpMust[Source any](source Enumerable[Source], comparer collate.Comparer[Source]) Enumerable[Source]

DistinctCmpMust is like DistinctCmp but panics in case of error.

func DistinctEq

func DistinctEq[Source any](source Enumerable[Source], equaler collate.Equaler[Source]) (Enumerable[Source], error)

DistinctEq returns distinct elements from a sequence using a specified equaler to compare values. If 'equaler' is nil collate.DeepEqualer is used. Order of elements in the result corresponds to the order of elements in 'source'.

func DistinctEqMust

func DistinctEqMust[Source any](source Enumerable[Source], equaler collate.Equaler[Source]) Enumerable[Source]

DistinctEqMust is like DistinctEq but panics in case of error.

Example

see the last two examples from Enumerable.Distinct help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.distinct

products := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
	{Name: "Apple", Code: 9},
	{Name: "lemon", Code: 12},
}
var eqf collate.Equaler[Product] = collate.EqualerFunc[Product](
	func(p1, p2 Product) bool {
		return p1.Code == p2.Code && strings.EqualFold(p1.Name, p2.Name)
	},
)
//Exclude duplicates.
distinctEq := DistinctEqMust(NewEnSliceEn(products...), eqf)
enr := distinctEq.GetEnumerator()
for enr.MoveNext() {
	product := enr.Current()
	fmt.Printf("%s %d\n", product.Name, product.Code)
}
Output:

apple 9
orange 4
lemon 12

func DistinctMust

func DistinctMust[Source any](source Enumerable[Source]) Enumerable[Source]

DistinctMust is like Distinct but panics in case of error.

Example

see the first example from Enumerable.Distinct help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.distinct

ages := []int{21, 46, 46, 55, 17, 21, 55, 55}
distinct := DistinctMust(NewEnSliceEn(ages...))
fmt.Println("Distinct ages:")
enr := distinct.GetEnumerator()
for enr.MoveNext() {
	age := enr.Current()
	fmt.Println(age)
}
Output:

Distinct ages:
21
46
55
17

func Empty

func Empty[Result any]() Enumerable[Result]

Empty returns an empty Enumerable that has a specified type argument.

Example

see the example from Enumerable.Empty help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.empty#examples

names1 := []string{"Hartono, Tommy"}
names2 := []string{"Adams, Terry", "Andersen, Henriette Thaulow", "Hedlund, Magnus", "Ito, Shu"}
names3 := []string{"Solanki, Ajay", "Hoeing, Helge", "Andersen, Henriette Thaulow", "Potra, Cristina", "Iallo, Lucio"}
namesList := []Enumerable[string]{
	NewEnSliceEn(names1...),
	NewEnSliceEn(names2...),
	NewEnSliceEn(names3...),
}
allNames := AggregateSeedMust(
	NewEnSliceEn(namesList...),
	Empty[string](),
	func(current, next Enumerable[string]) Enumerable[string] {
		// Only include arrays that have four or more elements
		if CountMust(next) > 3 {
			return UnionMust(current, next)
		}
		return current
	},
)
enr := allNames.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Println(name)
}
Output:

Adams, Terry
Andersen, Henriette Thaulow
Hedlund, Magnus
Ito, Shu
Solanki, Ajay
Hoeing, Helge
Potra, Cristina
Iallo, Lucio

func Except

func Except[Source any](first, second Enumerable[Source]) (Enumerable[Source], error)

Except produces the set difference of two sequences using collate.DeepEqualer to compare values. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptBy

func ExceptBy[Source, Key any](first Enumerable[Source], second Enumerable[Key], keySelector func(Source) Key) (Enumerable[Source], error)

ExceptBy produces the set difference of two sequences according to a specified key selector function and using collate.DeepEqualer as key equaler. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptByCmp

func ExceptByCmp[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) (Enumerable[Source], error)

ExceptByCmp produces the set difference of two sequences according to a specified key selector function and using a specified key comparer. (See DistinctCmp.) 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptByCmpMust

func ExceptByCmpMust[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) Enumerable[Source]

ExceptByCmpMust is like ExceptByCmp but panics in case of error.

func ExceptByEq

func ExceptByEq[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) (Enumerable[Source], error)

ExceptByEq produces the set difference of two sequences according to a specified key selector function and using a specified key equaler. If 'equaler' is nil collate.DeepEqualer is used. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptByEqMust

func ExceptByEqMust[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) Enumerable[Source]

ExceptByEqMust is like ExceptByEq but panics in case of error.

func ExceptByMust

func ExceptByMust[Source, Key any](first Enumerable[Source], second Enumerable[Key], keySelector func(Source) Key) Enumerable[Source]

ExceptByMust is like ExceptBy but panics in case of error.

func ExceptCmp

func ExceptCmp[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) (Enumerable[Source], error)

ExceptCmp produces the set difference of two sequences using 'comparer' to compare values. (See DistinctCmp.) 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptCmpMust

func ExceptCmpMust[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) Enumerable[Source]

ExceptCmpMust is like ExceptCmp but panics in case of error.

func ExceptEq

func ExceptEq[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) (Enumerable[Source], error)

ExceptEq produces the set difference of two sequences using 'equaler' to compare values. If 'equaler' is nil collate.DeepEqualer is used. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func ExceptEqMust

func ExceptEqMust[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) Enumerable[Source]

ExceptEqMust is like ExceptEq but panics in case of error.

Example

see the last two examples from Enumerable.Except help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.except

fruits1 := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
	{Name: "lemon", Code: 12},
}
fruits2 := []Product{
	{Name: "APPLE", Code: 9},
}
var equaler collate.Equaler[Product] = collate.EqualerFunc[Product](
	func(p1, p2 Product) bool {
		return p1.Code == p2.Code && strings.EqualFold(p1.Name, p2.Name)
	},
)
//Get all the elements from the first array except for the elements from the second array.
except := ExceptEqMust(
	NewEnSliceEn(fruits1...),
	NewEnSliceEn(fruits2...),
	equaler,
)
enr := except.GetEnumerator()
for enr.MoveNext() {
	product := enr.Current()
	fmt.Printf("%s %d\n", product.Name, product.Code)
}
Output:

orange 4
lemon 12

func ExceptMust

func ExceptMust[Source any](first, second Enumerable[Source]) Enumerable[Source]

ExceptMust is like Except but panics in case of error.

Example

see the first example from Enumerable.Except help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.except

numbers1 := NewEnSliceEn(2.0, 2.0, 2.1, 2.2, 2.3, 2.3, 2.4, 2.5)
numbers2 := NewEnSliceEn(2.2)
except := ExceptMust(numbers1, numbers2)
enr := except.GetEnumerator()
for enr.MoveNext() {
	number := enr.Current()
	fmt.Println(number)
}
Output:

2
2.1
2.3
2.4
2.5

func GroupBy

func GroupBy[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) (Enumerable[Grouping[Key, Source]], error)

GroupBy groups the elements of a sequence according to a specified key selector function. The keys are compared using collate.DeepEqualer. 'source' is enumerated immediately.

func GroupByEq

func GroupByEq[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) (Enumerable[Grouping[Key, Source]], error)

GroupByEq groups the elements of a sequence according to a specified key selector function and compares the keys using 'equaler'. If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func GroupByEqMust

func GroupByEqMust[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) Enumerable[Grouping[Key, Source]]

GroupByEqMust is like GroupByEq but panics in case of error.

func GroupByMust

func GroupByMust[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) Enumerable[Grouping[Key, Source]]

GroupByMust is like GroupBy but panics in case of error.

Example

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/grouping-data#query-expression-syntax-example

numbers := []int{35, 44, 200, 84, 3987, 4, 199, 329, 446, 208}
query := GroupByMust(
	NewEnSliceEn(numbers...),
	func(i int) int { return i % 2 },
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	group := enr.Current()
	if group.Key() == 0 {
		fmt.Println("\nEven numbers:")
	} else {
		fmt.Println("\nOdd numbers:")
	}
	enrGroup := group.GetEnumerator()
	for enrGroup.MoveNext() {
		i := enrGroup.Current()
		fmt.Println(i)
	}
}
Output:

Odd numbers:
35
3987
199
329

Even numbers:
44
200
84
4
446
208

func GroupByRes

func GroupByRes[Source, Key, Result any](source Enumerable[Source],
	keySelector func(Source) Key, resultSelector func(Key, Enumerable[Source]) Result) (Enumerable[Result], error)

GroupByRes groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The keys are compared using collate.DeepEqualer. 'source' is enumerated immediately.

func GroupByResEq

func GroupByResEq[Source, Key, Result any](source Enumerable[Source],
	keySelector func(Source) Key, resultSelector func(Key, Enumerable[Source]) Result, equaler collate.Equaler[Key]) (Enumerable[Result], error)

GroupByResEq groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The keys are compared using 'equaler'. If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func GroupByResEqMust

func GroupByResEqMust[Source, Key, Result any](source Enumerable[Source], keySelector func(Source) Key,
	resultSelector func(Key, Enumerable[Source]) Result, equaler collate.Equaler[Key]) Enumerable[Result]

GroupByResEqMust is like GroupByResEq but panics in case of error.

func GroupByResMust

func GroupByResMust[Source, Key, Result any](source Enumerable[Source],
	keySelector func(Source) Key, resultSelector func(Key, Enumerable[Source]) Result) Enumerable[Result]

GroupByResMust is like GroupByRes but panics in case of error.

Example

see GroupByEx3 example from Enumerable.GroupBy help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby

pets := []PetF{
	{Name: "Barley", Age: 8.3},
	{Name: "Boots", Age: 4.9},
	{Name: "Whiskers", Age: 1.5},
	{Name: "Daisy", Age: 4.3},
}
// Group PetF objects by the math.Floor of their Age.
// Then project a Result type from each group that consists of the Key,
// the Count of the group's elements, and the minimum and maximum Age in the group.
query := GroupByResMust(
	NewEnSliceEn(pets...),
	func(pet PetF) float64 { return math.Floor(pet.Age) },
	func(age float64, pets Enumerable[PetF]) Result {
		count := CountMust(pets)
		mn := MinSelMust(pets, func(pet PetF) float64 { return pet.Age })
		mx := MaxSelMust(pets, func(pet PetF) float64 { return pet.Age })
		return Result{Key: age, Count: count, Min: mn, Max: mx}
	},
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	result := enr.Current()
	fmt.Printf("\nAge group: %g\n", result.Key)
	fmt.Printf("Number of pets in this age group: %d\n", result.Count)
	fmt.Printf("Minimum age: %g\n", result.Min)
	fmt.Printf("Maximum age: %g\n", result.Max)
}
Output:

Age group: 8
Number of pets in this age group: 1
Minimum age: 8.3
Maximum age: 8.3

Age group: 4
Number of pets in this age group: 2
Minimum age: 4.3
Maximum age: 4.9

Age group: 1
Number of pets in this age group: 1
Minimum age: 1.5
Maximum age: 1.5

func GroupBySel

func GroupBySel[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) (Enumerable[Grouping[Key, Element]], error)

GroupBySel groups the elements of a sequence according to a specified key selector function and projects the elements for each group using a specified function. The keys are compared using collate.DeepEqualer. 'source' is enumerated immediately.

func GroupBySelEq

func GroupBySelEq[Source, Key, Element any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, equaler collate.Equaler[Key]) (Enumerable[Grouping[Key, Element]], error)

GroupBySelEq groups the elements of a sequence according to a key selector function. The keys are compared using 'equaler' and each group's elements are projected using a specified function. If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func GroupBySelEqMust

func GroupBySelEqMust[Source, Key, Element any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, equaler collate.Equaler[Key]) Enumerable[Grouping[Key, Element]]

GroupBySelEqMust is like GroupBySelEq but panics in case of error.

func GroupBySelMust

func GroupBySelMust[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) Enumerable[Grouping[Key, Element]]

GroupBySelMust is like GroupBySel but panics in case of error.

Example

see GroupByEx1 example from Enumerable.GroupBy help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
	{Name: "Daisy", Age: 4},
}
// Group the pets using Age as the key value and selecting only the Pet's Name for each value.
query := GroupBySelMust(
	NewEnSliceEn(pets...),
	func(pet Pet) int { return pet.Age },
	func(pet Pet) string { return pet.Name },
)
// Iterate over each Grouping in the collection.
enr := query.GetEnumerator()
for enr.MoveNext() {
	petGroup := enr.Current()
	// Print the key value of the Grouping.
	fmt.Println(petGroup.Key())
	enrNames := petGroup.GetEnumerator()
	// Iterate over each value in the Grouping and print the value.
	for enrNames.MoveNext() {
		name := enrNames.Current()
		fmt.Printf("  %s\n", name)
	}
}
Output:

8
  Barley
4
  Boots
  Daisy
1
  Whiskers

func GroupBySelRes

func GroupBySelRes[Source, Key, Element, Result any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, resultSelector func(Key, Enumerable[Element]) Result) (Enumerable[Result], error)

GroupBySelRes groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The elements of each group are projected using a specified function. Key values are compared using collate.DeepEqualer. 'source' is enumerated immediately.

func GroupBySelResEq

func GroupBySelResEq[Source, Key, Element, Result any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, resultSelector func(Key, Enumerable[Element]) Result, equaler collate.Equaler[Key]) (Enumerable[Result], error)

GroupBySelResEq groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. Key values are compared using 'equaler' and the elements of each group are projected using a specified function. If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func GroupBySelResEqMust

func GroupBySelResEqMust[Source, Key, Element, Result any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, resultSelector func(Key, Enumerable[Element]) Result, equaler collate.Equaler[Key]) Enumerable[Result]

GroupBySelResEqMust is like GroupBySelResEq but panics in case of error.

func GroupBySelResMust

func GroupBySelResMust[Source, Key, Element, Result any](source Enumerable[Source], keySelector func(Source) Key,
	elementSelector func(Source) Element, resultSelector func(Key, Enumerable[Element]) Result) Enumerable[Result]

GroupBySelResMust is like GroupBySelRes but panics in case of error.

Example

see GroupByEx4 example from Enumerable.GroupBy help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupby

pets := []PetF{
	{Name: "Barley", Age: 8.3},
	{Name: "Boots", Age: 4.9},
	{Name: "Whiskers", Age: 1.5},
	{Name: "Daisy", Age: 4.3},
}
// Group PetF.Age values by the math.Floor of the age.
// Then project a Result type from each group that consists of the Key,
// the Count of the group's elements, and the minimum and maximum Age in the group.
query := GroupBySelResMust(
	NewEnSliceEn(pets...),
	func(pet PetF) float64 { return math.Floor(pet.Age) },
	func(pet PetF) float64 { return pet.Age },
	func(baseAge float64, ages Enumerable[float64]) Result {
		count := CountMust(ages)
		min := MinMust(ages)
		max := MaxMust(ages)
		return Result{Key: baseAge, Count: count, Min: min, Max: max}
	},
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	result := enr.Current()
	fmt.Printf("\nAge group: %g\n", result.Key)
	fmt.Printf("Number of pets in this age group: %d\n", result.Count)
	fmt.Printf("Minimum age: %g\n", result.Min)
	fmt.Printf("Maximum age: %g\n", result.Max)
}
Output:

Age group: 8
Number of pets in this age group: 1
Minimum age: 8.3
Maximum age: 8.3

Age group: 4
Number of pets in this age group: 2
Minimum age: 4.3
Maximum age: 4.9

Age group: 1
Number of pets in this age group: 1
Minimum age: 1.5
Maximum age: 1.5

func GroupJoin

func GroupJoin[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Enumerable[Inner]) Result) (Enumerable[Result], error)

GroupJoin correlates the elements of two sequences based on equality of keys and groups the results. collate.DeepEqualer is used to compare keys. 'inner' is enumerated on the first [Enumerator.MoveNext] call.

func GroupJoinEq

func GroupJoinEq[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner],
	outerKeySelector func(Outer) Key, innerKeySelector func(Inner) Key,
	resultSelector func(Outer, Enumerable[Inner]) Result, equaler collate.Equaler[Key]) (Enumerable[Result], error)

GroupJoinEq correlates the elements of two sequences based on key equality and groups the results. 'equaler' is used to compare keys. If 'equaler' is nil collate.DeepEqualer is used. 'inner' is enumerated on the first [Enumerator.MoveNext] call.

func GroupJoinEqMust

func GroupJoinEqMust[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner],
	outerKeySelector func(Outer) Key, innerKeySelector func(Inner) Key,
	resultSelector func(Outer, Enumerable[Inner]) Result, equaler collate.Equaler[Key]) Enumerable[Result]

GroupJoinEqMust is like GroupJoinEq but panics in case of error.

func GroupJoinMust

func GroupJoinMust[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Enumerable[Inner]) Result) Enumerable[Result]

GroupJoinMust is like GroupJoin but panics in case of error.

Example (Ex1)

see GroupJoinEx1 example from Enumerable.GroupJoin help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.groupjoin

magnus := Person{Name: "Hedlund, Magnus"}
terry := Person{Name: "Adams, Terry"}
charlotte := Person{Name: "Weiss, Charlotte"}

barley := Pet{Name: "Barley", Owner: terry}
boots := Pet{Name: "Boots", Owner: terry}
whiskers := Pet{Name: "Whiskers", Owner: charlotte}
daisy := Pet{Name: "Daisy", Owner: magnus}

// Create a list where each element is an OwnerAndPets type that contains a person's name and
// a collection of names of the pets they own.
people := []Person{magnus, terry, charlotte}
pets := []Pet{barley, boots, whiskers, daisy}

query := GroupJoinMust(
	NewEnSliceEn(people...),
	NewEnSliceEn(pets...),
	Identity[Person],
	func(pet Pet) Person { return pet.Owner },
	func(person Person, pets Enumerable[Pet]) OwnerAndPets {
		return OwnerAndPets{
			OwnerName: person.Name,
			Pets:      SelectMust(pets, func(pet Pet) string { return pet.Name })}
	},
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	obj := enr.Current()
	// Output the owner's name.
	fmt.Printf("%s:\n", obj.OwnerName)
	// Output each of the owner's pet's names.
	enrPets := obj.Pets.GetEnumerator()
	for enrPets.MoveNext() {
		pet := enrPets.Current()
		fmt.Printf("  %s\n", pet)
	}
}
Output:

Hedlund, Magnus:
  Daisy
Adams, Terry:
  Barley
  Boots
Weiss, Charlotte:
  Whiskers
Example (Ex2)

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/join-operations#query-expression-syntax-examples https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/join-operations#groupjoin

products := []Product{
	{Name: "Cola", CategoryId: 0},
	{Name: "Tea", CategoryId: 0},
	{Name: "Apple", CategoryId: 1},
	{Name: "Kiwi", CategoryId: 1},
	{Name: "Carrot", CategoryId: 2},
}
categories := []Category{
	{Id: 0, CategoryName: "Beverage"},
	{Id: 1, CategoryName: "Fruit"},
	{Id: 2, CategoryName: "Vegetable"},
}
// Join categories and product based on CategoryId and grouping result
productGroups := GroupJoinMust(
	NewEnSliceEn(categories...),
	NewEnSliceEn(products...),
	func(category Category) int { return category.Id },
	func(product Product) int { return product.CategoryId },
	func(category Category, products Enumerable[Product]) Enumerable[Product] {
		return products
	},
)
enrGroupJoin := productGroups.GetEnumerator()
for enrGroupJoin.MoveNext() {
	fmt.Println("Group")
	productGroup := enrGroupJoin.Current()
	enrProductGroup := productGroup.GetEnumerator()
	for enrProductGroup.MoveNext() {
		product := enrProductGroup.Current()
		fmt.Printf("%8s\n", product.Name)
	}
}
Output:

Group
    Cola
     Tea
Group
   Apple
    Kiwi
Group
  Carrot

func Intersect

func Intersect[Source any](first, second Enumerable[Source]) (Enumerable[Source], error)

Intersect produces the set intersection of two sequences using collate.DeepEqualer to compare values. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectBy

func IntersectBy[Source, Key any](first Enumerable[Source], second Enumerable[Key], keySelector func(Source) Key) (Enumerable[Source], error)

IntersectBy produces the set intersection of two sequences according to a specified key selector function and using collate.DeepEqualer as key equaler. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectByCmp

func IntersectByCmp[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) (Enumerable[Source], error)

IntersectByCmp produces the set intersection of two sequences according to a specified key selector function and using a specified key comparer. (See DistinctCmp.) 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectByCmpMust

func IntersectByCmpMust[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) Enumerable[Source]

IntersectByCmpMust is like IntersectByCmp but panics in case of error.

func IntersectByEq

func IntersectByEq[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) (Enumerable[Source], error)

IntersectByEq produces the set intersection of two sequences according to a specified key selector function and using a specified key equaler. If 'equaler' is nil collate.DeepEqualer is used. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectByEqMust

func IntersectByEqMust[Source, Key any](first Enumerable[Source], second Enumerable[Key],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) Enumerable[Source]

IntersectByEqMust is like IntersectByEq but panics in case of error.

func IntersectByMust

func IntersectByMust[Source, Key any](first Enumerable[Source], second Enumerable[Key], keySelector func(Source) Key) Enumerable[Source]

IntersectByMust is like IntersectBy but panics in case of error.

func IntersectCmp

func IntersectCmp[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) (Enumerable[Source], error)

IntersectCmp produces the set intersection of two sequences using 'comparer' to compare values. (See DistinctCmp.) 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectCmpMust

func IntersectCmpMust[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) Enumerable[Source]

IntersectCmpMust is like IntersectCmp but panics in case of error.

func IntersectEq

func IntersectEq[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) (Enumerable[Source], error)

IntersectEq produces the set intersection of two sequences using 'equaler' to compare values. If 'equaler' is nil collate.DeepEqualer is used. 'second' is enumerated on the first [Enumerator.MoveNext] call. Order of elements in the result corresponds to the order of elements in 'first'.

func IntersectEqMust

func IntersectEqMust[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) Enumerable[Source]

IntersectEqMust is like IntersectEq but panics in case of error.

Example

see the second and third examples from Enumerable.Intersect help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.intersect

store1 := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
}
store2 := []Product{
	{Name: "apple", Code: 9},
	{Name: "lemon", Code: 12},
}
// Get the products from the first array that have duplicates in the second array.
var equaler collate.Equaler[Product] = collate.EqualerFunc[Product](
	func(p1, p2 Product) bool {
		return p1.Name == p2.Name && p1.Code == p2.Code
	},
)
intersectEq := IntersectEqMust(
	NewEnSliceEn(store1...),
	NewEnSliceEn(store2...),
	equaler,
)
enr := intersectEq.GetEnumerator()
for enr.MoveNext() {
	product := enr.Current()
	fmt.Printf("%s %d\n", product.Name, product.Code)
}
Output:

apple 9

func IntersectMust

func IntersectMust[Source any](first, second Enumerable[Source]) Enumerable[Source]

IntersectMust is like Intersect but panics in case of error.

Example

see the first example from Enumerable.Intersect help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.intersect

id1 := NewEnSliceEn(44, 26, 92, 30, 71, 38)
id2 := NewEnSliceEn(39, 59, 83, 47, 26, 4, 30)
intersect := IntersectMust(id1, id2)
enr := intersect.GetEnumerator()
for enr.MoveNext() {
	id := enr.Current()
	fmt.Println(id)
}
Output:

26
30

func Join

func Join[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Inner) Result) (Enumerable[Result], error)

Join correlates the elements of two sequences based on matching keys. collate.DeepEqualer is used to compare keys. 'inner' is enumerated on the first [Enumerator.MoveNext] call.

func JoinEq

func JoinEq[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Inner) Result, equaler collate.Equaler[Key]) (Enumerable[Result], error)

JoinEq correlates the elements of two sequences based on matching keys. 'equaler' is used to compare keys. If 'equaler' is nil collate.DeepEqualer is used. 'inner' is enumerated on the first [Enumerator.MoveNext] call.

Similar to the keys equality functionality may be achieved using appropriate key selectors. See [TestJoinEqMust_CustomComparer] test for usage of case insensitive string keys.

func JoinEqMust

func JoinEqMust[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Inner) Result, equaler collate.Equaler[Key]) Enumerable[Result]

JoinEqMust is like JoinEq but panics in case of error.

func JoinMust

func JoinMust[Outer, Inner, Key, Result any](outer Enumerable[Outer], inner Enumerable[Inner], outerKeySelector func(Outer) Key,
	innerKeySelector func(Inner) Key, resultSelector func(Outer, Inner) Result) Enumerable[Result]

JoinMust is like Join but panics in case of error.

Example (Ex1)

see JoinEx1 example from Enumerable.Join help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.join

magnus := Person{Name: "Hedlund, Magnus"}
terry := Person{Name: "Adams, Terry"}
charlotte := Person{Name: "Weiss, Charlotte"}

barley := Pet{Name: "Barley", Owner: terry}
boots := Pet{Name: "Boots", Owner: terry}
whiskers := Pet{Name: "Whiskers", Owner: charlotte}
daisy := Pet{Name: "Daisy", Owner: magnus}

people := []Person{magnus, terry, charlotte}
pets := []Pet{barley, boots, whiskers, daisy}

// Create a list of Person-Pet pairs where each element is an OwnerNameAndPetName type that contains a
// Pet's name and the name of the Person that owns the Pet.
join := JoinMust(
	NewEnSliceEn(people...),
	NewEnSliceEn(pets...),
	Identity[Person],
	func(pet Pet) Person { return pet.Owner },
	func(person Person, pet Pet) OwnerNameAndPetName {
		return OwnerNameAndPetName{Owner: person.Name, Pet: pet.Name}
	},
)
enr := join.GetEnumerator()
for enr.MoveNext() {
	obj := enr.Current()
	fmt.Printf("%s - %s\n", obj.Owner, obj.Pet)
}
Output:

Hedlund, Magnus - Daisy
Adams, Terry - Barley
Adams, Terry - Boots
Weiss, Charlotte - Whiskers
Example (Ex2)

https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/join-operations#query-expression-syntax-examples https://learn.microsoft.com/dotnet/csharp/programming-guide/concepts/linq/join-operations#join

products := []Product{
	{Name: "Cola", CategoryId: 0},
	{Name: "Tea", CategoryId: 0},
	{Name: "Apple", CategoryId: 1},
	{Name: "Kiwi", CategoryId: 1},
	{Name: "Carrot", CategoryId: 2},
}
categories := []Category{
	{Id: 0, CategoryName: "Beverage"},
	{Id: 1, CategoryName: "Fruit"},
	{Id: 2, CategoryName: "Vegetable"},
}
// Join products and categories based on CategoryId
join := JoinMust(
	NewEnSliceEn(products...),
	NewEnSliceEn(categories...),
	func(product Product) int { return product.CategoryId },
	func(category Category) int { return category.Id },
	func(product Product, category Category) string {
		return fmt.Sprintf("%s - %s", product.Name, category.CategoryName)
	},
)
enr := join.GetEnumerator()
for enr.MoveNext() {
	item := enr.Current()
	fmt.Println(item)
}
Output:

Cola - Beverage
Tea - Beverage
Apple - Fruit
Kiwi - Fruit
Carrot - Vegetable

func NewEnChanEn added in v2.8.0

func NewEnChanEn[T any](ch <-chan T) Enumerable[T]

NewEnChanEn creates a new EnChan with a specified channel as contents and returns it as Enumerable.

func NewEnFuncEn added in v2.10.0

func NewEnFuncEn[T any](mvNxt func() bool, crrnt func() T, rst func()) Enumerable[T]

NewEnFuncEn creates a new EnFunc with a specified functions as the Enumerable's methods and returns it as Enumerable.

func NewEnMapEn added in v2.9.0

func NewEnMapEn[Key comparable, Element any](m map[Key]Element) Enumerable[generichelper.Tuple2[Key, Element]]

NewEnMapEn creates a new EnMap with a specified map as contents and returns it as Enumerable.

func NewEnSliceEn added in v2.7.0

func NewEnSliceEn[T any](slice ...T) Enumerable[T]

NewEnSliceEn creates a new EnSlice with a specified slice as contents and returns it as Enumerable.

func OfType

func OfType[Source, Result any](source Enumerable[Source]) (Enumerable[Result], error)

OfType filters the elements of an Enumerable based on a specified type.

func OfTypeMust

func OfTypeMust[Source, Result any](source Enumerable[Source]) Enumerable[Result]

OfTypeMust is like OfType but panics in case of error.

func OnChan

func OnChan[T any](ch <-chan T) Enumerable[T]

OnChan creates a new Enumerable based on the provided channel. (Retained for backwards compatibility. Use NewEnChanEn instead.)

func OnFactory

func OnFactory[T any](factory func() Enumerator[T]) Enumerable[T]

OnFactory creates a new Enumerable based on the provided Enumerator factory.

func OnMap

func OnMap[Key comparable, Element any](m map[Key]Element) Enumerable[generichelper.Tuple2[Key, Element]]

OnMap creates a new Enumerable based on the provided map. (Retained for backwards compatibility. Use NewEnMapEn instead.)

func Prepend

func Prepend[Source any](source Enumerable[Source], element Source) (Enumerable[Source], error)

Prepend adds a value to the beginning of the sequence.

func PrependMust

func PrependMust[Source any](source Enumerable[Source], element Source) Enumerable[Source]

PrependMust is like Prepend but panics in case of error.

func Range

func Range(start, count int) (Enumerable[int], error)

Range generates a sequence of ints within a specified range.

func RangeMust

func RangeMust(start, count int) Enumerable[int]

RangeMust is like Range but panics in case of error.

Example

see the example from Enumerable.Range help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.range#examples

// Generate a sequence of integers from 1 to 10 and then select their squares.
squares := SelectMust(RangeMust(1, 10), func(x int) int { return x * x })
enr := squares.GetEnumerator()
for enr.MoveNext() {
	num := enr.Current()
	fmt.Println(num)
}
Output:

1
4
9
16
25
36
49
64
81
100

func Repeat

func Repeat[Result any](element Result, count int) (Enumerable[Result], error)

Repeat generates a sequence that contains one repeated value.

func RepeatMust

func RepeatMust[Result any](element Result, count int) Enumerable[Result]

RepeatMust is like Repeat but panics in case of error.

Example

see the example from Enumerable.Repeat help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.repeat#examples

strs := RepeatMust("I like programming.", 4)
enr := strs.GetEnumerator()
for enr.MoveNext() {
	str := enr.Current()
	fmt.Println(str)
}
Output:

I like programming.
I like programming.
I like programming.
I like programming.

func Reverse

func Reverse[Source any](source Enumerable[Source]) (Enumerable[Source], error)

Reverse inverts the order of the elements in a sequence.

func ReverseMust

func ReverseMust[Source any](source Enumerable[Source]) Enumerable[Source]

ReverseMust is like Reverse but panics in case of error.

Example

see the example from Enumerable.Reverse help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.reverse#examples

apple := []string{"a", "p", "p", "l", "e"}
reverse := ReverseMust(
	NewEnSliceEn(apple...),
)
enr := reverse.GetEnumerator()
for enr.MoveNext() {
	chr := enr.Current()
	fmt.Printf("%v ", chr)
}
fmt.Println()
Output:

e l p p a

func Select

func Select[Source, Result any](source Enumerable[Source], selector func(Source) Result) (Enumerable[Result], error)

Select projects each element of a sequence into a new form.

func SelectIdx

func SelectIdx[Source, Result any](source Enumerable[Source], selector func(Source, int) Result) (Enumerable[Result], error)

SelectIdx projects each element of a sequence into a new form by incorporating the element's index.

func SelectIdxMust

func SelectIdxMust[Source, Result any](source Enumerable[Source], selector func(Source, int) Result) Enumerable[Result]

SelectIdxMust is like SelectIdx but panics in case of error.

Example
fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
query := SelectIdxMust(
	NewEnSliceEn(fruits...),
	func(fruit string, index int) indexstr {
		return indexstr{index: index, str: fruit[:index]}
	},
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	obj := enr.Current()
	fmt.Printf("%+v\n", obj)
}
Output:

{index:0 str:}
{index:1 str:b}
{index:2 str:ma}
{index:3 str:ora}
{index:4 str:pass}
{index:5 str:grape}

func SelectMany

func SelectMany[Source, Result any](source Enumerable[Source], selector func(Source) Enumerable[Result]) (Enumerable[Result], error)

SelectMany projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence.

func SelectManyColl

func SelectManyColl[Source, Collection, Result any](source Enumerable[Source],
	collectionSelector func(Source) Enumerable[Collection], resultSelector func(Source, Collection) Result) (Enumerable[Result], error)

SelectManyColl projects each element of a sequence to an Enumerable, flattens the resulting sequences into one sequence and invokes a result selector function on each element therein.

func SelectManyCollIdx

func SelectManyCollIdx[Source, Collection, Result any](source Enumerable[Source],
	collectionSelector func(Source, int) Enumerable[Collection], resultSelector func(Source, Collection) Result) (Enumerable[Result], error)

SelectManyCollIdx projects each element of a sequence and its index to an Enumerable, flattens the resulting sequences into one sequence and invokes a result selector function on each element therein.

func SelectManyCollIdxMust

func SelectManyCollIdxMust[Source, Collection, Result any](source Enumerable[Source],
	collectionSelector func(Source, int) Enumerable[Collection], resultSelector func(Source, Collection) Result) Enumerable[Result]

SelectManyCollIdxMust is like SelectManyCollIdx but panics in case of error.

func SelectManyCollMust

func SelectManyCollMust[Source, Collection, Result any](source Enumerable[Source],
	collectionSelector func(Source) Enumerable[Collection], resultSelector func(Source, Collection) Result) Enumerable[Result]

SelectManyCollMust is like SelectManyColl but panics in case of error.

Example

see SelectManyEx3 example from Enumerable.SelectMany help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.selectmany

petOwners := []PetOwner{
	{Name: "Higa", Pets: []string{"Scruffy", "Sam"}},
	{Name: "Ashkenazi", Pets: []string{"Walker", "Sugar"}},
	{Name: "Price", Pets: []string{"Scratches", "Diesel"}},
	{Name: "Hines", Pets: []string{"Dusty"}},
}
// Project all pet's names together with the pet's owner.
selectMany := SelectManyCollMust(
	NewEnSliceEn(petOwners...),
	func(petOwner PetOwner) Enumerable[string] {
		return NewEnSlice(petOwner.Pets...)
	},
	func(petOwner PetOwner, petName string) OwnerAndPet {
		return OwnerAndPet{petOwner: petOwner, petName: petName}
	},
)
// Filter only pet's names that start with S.
where := WhereMust(selectMany,
	func(ownerAndPet OwnerAndPet) bool {
		return strings.HasPrefix(ownerAndPet.petName, "S")
	},
)
// Project the pet owner's name and the pet's name.
selectEn := SelectMust(where,
	func(ownerAndPet OwnerAndPet) OwnerNameAndPetName {
		return OwnerNameAndPetName{Owner: ownerAndPet.petOwner.Name, Pet: ownerAndPet.petName}
	},
)
enr := selectEn.GetEnumerator()
for enr.MoveNext() {
	obj := enr.Current()
	fmt.Printf("%+v\n", obj)
}
Output:

{Owner:Higa Pet:Scruffy}
{Owner:Higa Pet:Sam}
{Owner:Ashkenazi Pet:Sugar}
{Owner:Price Pet:Scratches}

func SelectManyIdx

func SelectManyIdx[Source, Result any](source Enumerable[Source], selector func(Source, int) Enumerable[Result]) (Enumerable[Result], error)

SelectManyIdx projects each element of a sequence and its index to an Enumerable and flattens the resulting sequences into one sequence.

func SelectManyIdxMust

func SelectManyIdxMust[Source, Result any](source Enumerable[Source], selector func(Source, int) Enumerable[Result]) Enumerable[Result]

SelectManyIdxMust is like SelectManyIdx but panics in case of error.

Example

see SelectManyEx2 example from Enumerable.SelectMany help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.selectmany

petOwners := []PetOwner{
	{Name: "Higa, Sidney", Pets: []string{"Scruffy", "Sam"}},
	{Name: "Ashkenazi, Ronen", Pets: []string{"Walker", "Sugar"}},
	{Name: "Price, Vernette", Pets: []string{"Scratches", "Diesel"}},
	{Name: "Hines, Patrick", Pets: []string{"Dusty"}},
}
// Project the items in the array by appending the index of each PetOwner
// to each pet's name in that petOwner's array of pets.
query := SelectManyIdxMust(
	NewEnSliceEn(petOwners...),
	func(petOwner PetOwner, index int) Enumerable[string] {
		return SelectMust(
			NewEnSliceEn(petOwner.Pets...),
			func(pet string) string { return strconv.Itoa(index) + pet },
		)
	},
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	pet := enr.Current()
	fmt.Println(pet)
}
Output:

0Scruffy
0Sam
1Walker
1Sugar
2Scratches
2Diesel
3Dusty

func SelectManyMust

func SelectManyMust[Source, Result any](source Enumerable[Source], selector func(Source) Enumerable[Result]) Enumerable[Result]

SelectManyMust is like SelectMany but panics in case of error.

Example (Ex1)

see the second example from Enumerable.Concat help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.concat#examples

cats := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
dogs := []Pet{
	{Name: "Bounder", Age: 3},
	{Name: "Snoopy", Age: 14},
	{Name: "Fido", Age: 9},
}
query := SelectManyMust(
	NewEnSliceEn(
		SelectMust(
			NewEnSliceEn(cats...),
			func(cat Pet) string { return cat.Name },
		),
		SelectMust(
			NewEnSliceEn(dogs...),
			func(dog Pet) string { return dog.Name },
		),
	),
	Identity[Enumerable[string]],
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	name := enr.Current()
	fmt.Println(name)
}
Output:

Barley
Boots
Whiskers
Bounder
Snoopy
Fido
Example (Ex2)

see SelectManyEx1 example from Enumerable.SelectMany help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.selectmany

petOwners := []PetOwner{
	{Name: "Higa, Sidney", Pets: []string{"Scruffy", "Sam"}},
	{Name: "Ashkenazi, Ronen", Pets: []string{"Walker", "Sugar"}},
	{Name: "Price, Vernette", Pets: []string{"Scratches", "Diesel"}},
}

// Query using SelectMany().
query1 := SelectManyMust(
	NewEnSliceEn(petOwners...),
	func(petOwner PetOwner) Enumerable[string] { return NewEnSlice(petOwner.Pets...) },
)
fmt.Println("Using SelectMany():")
// Only one for loop is required to iterate through the results since it is a one-dimensional collection.
enr1 := query1.GetEnumerator()
for enr1.MoveNext() {
	pet := enr1.Current()
	fmt.Println(pet)
}

// This code shows how to use Select() instead of SelectMany().
query2 := SelectMust(
	NewEnSliceEn(petOwners...),
	func(petOwner PetOwner) Enumerable[string] {
		return NewEnSlice(petOwner.Pets...)
	},
)
fmt.Println("\nUsing Select():")
// Notice that two foreach loops are required to iterate through the results
// because the query returns a collection of arrays.
enr2 := query2.GetEnumerator()
for enr2.MoveNext() {
	petList := enr2.Current()
	enrPetList := petList.GetEnumerator()
	for enrPetList.MoveNext() {
		pet := enrPetList.Current()
		fmt.Println(pet)
	}
	fmt.Println()
}
Output:

Using SelectMany():
Scruffy
Sam
Walker
Sugar
Scratches
Diesel

Using Select():
Scruffy
Sam

Walker
Sugar

Scratches
Diesel

func SelectMust

func SelectMust[Source, Result any](source Enumerable[Source], selector func(Source) Result) Enumerable[Result]

SelectMust is like Select but panics in case of error.

Example (Ex1)

see the first example from Enumerable.Select help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.select

squares := SelectMust(
	RangeMust(1, 10),
	func(x int) int { return x * x },
)
enr := squares.GetEnumerator()
for enr.MoveNext() {
	num := enr.Current()
	fmt.Println(num)
}
Output:

1
4
9
16
25
36
49
64
81
100
Example (Ex2)
numbers := []string{"one", "two", "three", "four", "five"}
fmt.Println(ToStringDef(
	SelectMust(
		NewEnSliceEn(numbers...),
		func(s string) string {
			return string(s[0]) + string(s[len(s)-1])
		},
	),
))
fmt.Println(ToStringDef(
	SelectMust(
		NewEnSliceEn(numbers...),
		func(s string) string {
			runes := []rune(s)
			reversedRunes := ToSliceMust(
				ReverseMust(
					NewEnSliceEn(runes...),
				),
			)
			return string(reversedRunes)
		},
	),
))
Output:

[oe to te fr fe]
[eno owt eerht ruof evif]

func Skip

func Skip[Source any](source Enumerable[Source], count int) (Enumerable[Source], error)

Skip bypasses a specified number of elements in a sequence and then returns the remaining elements.

func SkipLast

func SkipLast[Source any](source Enumerable[Source], count int) (Enumerable[Source], error)

SkipLast returns a new Enumerable that contains the elements from 'source' with the last 'count' elements of the source collection omitted.

func SkipLastMust

func SkipLastMust[Source any](source Enumerable[Source], count int) Enumerable[Source]

SkipLastMust is like SkipLast but panics in case of error.

func SkipMust

func SkipMust[Source any](source Enumerable[Source], count int) Enumerable[Source]

SkipMust is like Skip but panics in case of error.

Example

see the example from Enumerable.Skip help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.skip#examples

grades := []int{59, 82, 70, 56, 92, 98, 85}
orderedGrades := OrderByDescMust(
	NewEnSliceEn(grades...),
)
lowerGrades := SkipMust[int](orderedGrades, 3)
fmt.Println("All grades except the top three are:")
enr := lowerGrades.GetEnumerator()
for enr.MoveNext() {
	grade := enr.Current()
	fmt.Println(grade)
}
Output:

All grades except the top three are:
82
70
59
56

func SkipWhile

func SkipWhile[Source any](source Enumerable[Source], predicate func(Source) bool) (Enumerable[Source], error)

SkipWhile bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements.

func SkipWhileIdx

func SkipWhileIdx[Source any](source Enumerable[Source], predicate func(Source, int) bool) (Enumerable[Source], error)

SkipWhileIdx bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function.

func SkipWhileIdxMust

func SkipWhileIdxMust[Source any](source Enumerable[Source], predicate func(Source, int) bool) Enumerable[Source]

SkipWhileIdxMust is like SkipWhileIdx but panics in case of error.

Example

see the first example from Enumerable.SkipWhile help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.skipwhile

amounts := []int{5000, 2500, 9000, 8000, 6500, 4000, 1500, 5500}
skipWhileIdx := SkipWhileIdxMust(
	NewEnSliceEn(amounts...),
	func(amount, index int) bool { return amount > index*1000 },
)
enr := skipWhileIdx.GetEnumerator()
for enr.MoveNext() {
	amount := enr.Current()
	fmt.Println(amount)
}
Output:

4000
1500
5500

func SkipWhileMust

func SkipWhileMust[Source any](source Enumerable[Source], predicate func(Source) bool) Enumerable[Source]

SkipWhileMust is like SkipWhile but panics in case of error.

Example

see the second example from Enumerable.SkipWhile help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.skipwhile

grades := []int{59, 82, 70, 56, 92, 98, 85}
orderedGrades := OrderByDescMust(
	NewEnSliceEn(grades...),
)
lowerGrades := SkipWhileMust[int](orderedGrades,
	func(grade int) bool { return grade >= 80 },
)
fmt.Println("All grades below 80:")
enr := lowerGrades.GetEnumerator()
for enr.MoveNext() {
	grade := enr.Current()
	fmt.Println(grade)
}
Output:

All grades below 80:
70
59
56

func Take

func Take[Source any](source Enumerable[Source], count int) (Enumerable[Source], error)

Take returns a specified number of contiguous elements from the start of a sequence.

func TakeLast

func TakeLast[Source any](source Enumerable[Source], count int) (Enumerable[Source], error)

TakeLast returns a new Enumerable that contains the last 'count' elements from 'source'.

func TakeLastMust

func TakeLastMust[Source any](source Enumerable[Source], count int) Enumerable[Source]

TakeLastMust is like TakeLast but panics in case of error.

func TakeMust

func TakeMust[Source any](source Enumerable[Source], count int) Enumerable[Source]

TakeMust is like Take but panics in case of error.

Example

see the example from Enumerable.Take help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.take

grades := []int{59, 82, 70, 56, 92, 98, 85}
orderedGrades := OrderByDescMust(
	NewEnSliceEn(grades...),
)
topThreeGrades := TakeMust[int](orderedGrades, 3)
fmt.Println("The top three grades are:")
enr := topThreeGrades.GetEnumerator()
for enr.MoveNext() {
	grade := enr.Current()
	fmt.Println(grade)
}
Output:

The top three grades are:
98
92
85

func TakeWhile

func TakeWhile[Source any](source Enumerable[Source], predicate func(Source) bool) (Enumerable[Source], error)

TakeWhile returns elements from a sequence as long as a specified condition is true.

func TakeWhileIdx

func TakeWhileIdx[Source any](source Enumerable[Source], predicate func(Source, int) bool) (Enumerable[Source], error)

TakeWhileIdx returns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function.

func TakeWhileIdxMust

func TakeWhileIdxMust[Source any](source Enumerable[Source], predicate func(Source, int) bool) Enumerable[Source]

TakeWhileIdxMust is like TakeWhileIdx but panics in case of error.

Example

see the first example from Enumerable.TakeWhile help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.takewhile

fruits := []string{"apple", "passionfruit", "banana", "mango", "orange", "blueberry", "grape", "strawberry"}
takeWhileIdx := TakeWhileIdxMust(
	NewEnSliceEn(fruits...),
	func(fruit string, index int) bool {
		return len(fruit) >= index
	},
)
enr := takeWhileIdx.GetEnumerator()
for enr.MoveNext() {
	fruit := enr.Current()
	fmt.Println(fruit)
}
Output:

apple
passionfruit
banana
mango
orange
blueberry

func TakeWhileMust

func TakeWhileMust[Source any](source Enumerable[Source], predicate func(Source) bool) Enumerable[Source]

TakeWhileMust is like TakeWhile but panics in case of error.

Example

see the second example from Enumerable.TakeWhile help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.takewhile

fruits := []string{"apple", "banana", "mango", "orange", "passionfruit", "grape"}
takeWhile := TakeWhileMust(
	NewEnSliceEn(fruits...),
	func(fruit string) bool {
		return collate.CaseInsensitiveComparer.Compare("orange", fruit) != 0
	},
)
enr := takeWhile.GetEnumerator()
for enr.MoveNext() {
	fruit := enr.Current()
	fmt.Println(fruit)
}
Output:

apple
banana
mango

func ToEnString

func ToEnString[T any](en Enumerable[T]) Enumerable[string]

ToEnString converts a sequence to [Enumerable[string]].

If 'en' is nil, nil is returned.

func Union

func Union[Source any](first, second Enumerable[Source]) (Enumerable[Source], error)

Union produces the set union of two sequences using collate.DeepEqualer to compare values.

func UnionBy

func UnionBy[Source, Key any](first, second Enumerable[Source], keySelector func(Source) Key) (Enumerable[Source], error)

UnionBy produces the set union of two sequences according to a specified key selector function and using collate.DeepEqualer as key equaler.

func UnionByCmp

func UnionByCmp[Source, Key any](first, second Enumerable[Source],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) (Enumerable[Source], error)

UnionByCmp produces the set union of two sequences according to a specified key selector function and using a specified key comparer. (See DistinctCmp.)

func UnionByCmpMust

func UnionByCmpMust[Source, Key any](first, second Enumerable[Source],
	keySelector func(Source) Key, comparer collate.Comparer[Key]) Enumerable[Source]

UnionByCmpMust is like UnionByCmp but panics in case of error.

func UnionByEq

func UnionByEq[Source, Key any](first, second Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) (Enumerable[Source], error)

UnionByEq produces the set union of two sequences according to a specified key selector function and using a specified key equaler. If 'equaler' is nil collate.DeepEqualer is used.

func UnionByEqMust

func UnionByEqMust[Source, Key any](first, second Enumerable[Source],
	keySelector func(Source) Key, equaler collate.Equaler[Key]) Enumerable[Source]

UnionByEqMust is like UnionByEq but panics in case of error.

func UnionByMust

func UnionByMust[Source, Key any](first, second Enumerable[Source], keySelector func(Source) Key) Enumerable[Source]

UnionByMust is like UnionBy but panics in case of error.

func UnionCmp

func UnionCmp[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) (Enumerable[Source], error)

UnionCmp produces the set union of two sequences using 'comparer' to compare values. (See DistinctCmp.)

func UnionCmpMust

func UnionCmpMust[Source any](first, second Enumerable[Source], comparer collate.Comparer[Source]) Enumerable[Source]

UnionCmpMust is like UnionCmp but panics in case of error.

func UnionEq

func UnionEq[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) (Enumerable[Source], error)

UnionEq produces the set union of two sequences using 'equaler' to compare values. If 'equaler' is nil collate.DeepEqualer is used.

func UnionEqMust

func UnionEqMust[Source any](first, second Enumerable[Source], equaler collate.Equaler[Source]) Enumerable[Source]

UnionEqMust is like UnionEq but panics in case of error.

Example

see the last example from Enumerable.Union help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.union

store1 := []Product{
	{Name: "apple", Code: 9},
	{Name: "orange", Code: 4},
}
store2 := []Product{
	{Name: "apple", Code: 9},
	{Name: "lemon", Code: 12},
}
//Get the products from the both arrays excluding duplicates.
var equaler collate.Equaler[Product] = collate.EqualerFunc[Product](
	func(p1, p2 Product) bool {
		return p1.Code == p2.Code && p1.Name == p2.Name
	},
)
unionEq := UnionEqMust(
	NewEnSliceEn(store1...),
	NewEnSliceEn(store2...),
	equaler,
)
enr := unionEq.GetEnumerator()
for enr.MoveNext() {
	product := enr.Current()
	fmt.Printf("%s %d\n", product.Name, product.Code)
}
Output:

apple 9
orange 4
lemon 12

func UnionMust

func UnionMust[Source any](first, second Enumerable[Source]) Enumerable[Source]

UnionMust is like Union but panics in case of error.

Example

see the first example from Enumerable.Union help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.union

ints1 := []int{5, 3, 9, 7, 5, 9, 3, 7}
ints2 := []int{8, 3, 6, 4, 4, 9, 1, 0}
union := UnionMust(
	NewEnSliceEn(ints1...),
	NewEnSliceEn(ints2...),
)
enr := union.GetEnumerator()
for enr.MoveNext() {
	num := enr.Current()
	fmt.Printf("%d ", num)
}
Output:

5 3 9 7 8 6 4 1 0

func Where

func Where[Source any](source Enumerable[Source], predicate func(Source) bool) (Enumerable[Source], error)

Where filters a sequence of values based on a predicate.

func WhereIdx

func WhereIdx[Source any](source Enumerable[Source], predicate func(Source, int) bool) (Enumerable[Source], error)

WhereIdx filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function.

func WhereIdxMust

func WhereIdxMust[Source any](source Enumerable[Source], predicate func(Source, int) bool) Enumerable[Source]

WhereIdxMust is like WhereIdx but panics in case of error.

Example (Ex1)

see the last example from Enumerable.Where help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.where

numbers := []int{0, 30, 20, 15, 90, 85, 40, 75}
query := WhereIdxMust(
	NewEnSliceEn(numbers...),
	func(number, index int) bool { return number <= index*10 },
)
ForEach(context.Background(), query,
	func(number int) error {
		fmt.Println(number)
		return nil
	},
)
Output:

0
20
15
40
Example (Ex2)
fmt.Println(ToStringDef(
	WhereIdxMust(
		NewEnSliceEn("one", "two", "three", "four", "five"),
		func(s string, i int) bool { return len(s) == i },
	),
))
fmt.Println(ToStringDef(
	WhereIdxMust(
		ReverseMust(
			NewEnSliceEn("one", "two", "three", "four", "five"),
		),
		func(s string, i int) bool { return len(s) == i },
	),
))
fmt.Println(ToStringDef(
	WhereIdxMust[string](
		OrderByMust(
			NewEnSliceEn("one", "two", "three", "four", "five"),
		),
		func(s string, i int) bool { return len(s) > i },
	),
))
Output:

[five]
[two]
[five four one three]

func WhereMust

func WhereMust[Source any](source Enumerable[Source], predicate func(Source) bool) Enumerable[Source]

WhereMust is like Where but panics in case of error.

Example (Ex1)

see the first example from Enumerable.Where help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.where

fruits := []string{"apple", "passionfruit", "banana", "mango", "orange", "blueberry", "grape", "strawberry"}
where := WhereMust(
	NewEnSliceEn(fruits...),
	func(fruit string) bool { return len(fruit) < 6 },
)
enr := where.GetEnumerator()
for enr.MoveNext() {
	fruit := enr.Current()
	fmt.Println(fruit)
}
Output:

apple
mango
grape
Example (Ex2)
fmt.Println(ToStringDef(
	WhereMust(
		RangeMust(1, 10),
		func(i int) bool { return i%2 == 0 },
	),
))
fmt.Println(ToStringDef(
	WhereMust(
		NewEnSliceEn("one", "two", "three", "four", "five"),
		func(s string) bool { return strings.HasSuffix(s, "e") },
	),
))
Output:

[2 4 6 8 10]
[one three five]

func Zip

func Zip[First, Second, Result any](first Enumerable[First], second Enumerable[Second],
	resultSelector func(First, Second) Result) (Enumerable[Result], error)

Zip applies a specified function to the corresponding elements of two sequences, producing a sequence of the results.

func ZipMust

func ZipMust[First, Second, Result any](first Enumerable[First], second Enumerable[Second],
	resultSelector func(First, Second) Result) Enumerable[Result]

ZipMust is like Zip but panics in case of error.

Example

see the example from Enumerable.Zip help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.zip

numbers := []int{1, 2, 3, 4}
words := []string{"one", "two", "three"}
zip := ZipMust(
	NewEnSliceEn(numbers...),
	NewEnSliceEn(words...),
	func(first int, second string) string { return fmt.Sprintf("%d %s", first, second) },
)
enr := zip.GetEnumerator()
for enr.MoveNext() {
	item := enr.Current()
	fmt.Println(item)
}
Output:

1 one
2 two
3 three

type Enumerator

type Enumerator[T any] interface {

	// [MoveNext] advances the enumerator to the next element of the sequence.
	//
	// [MoveNext]: https://learn.microsoft.com/dotnet/api/system.collections.ienumerator.movenext
	MoveNext() bool

	// [Current] returns the element in the sequence at the current position of the enumerator.
	//
	// [Current]: https://learn.microsoft.com/dotnet/api/system.collections.generic.ienumerator-1.current
	Current() T

	// [Reset] sets the enumerator to its initial position, which is before the first element in the sequence.
	// See also:
	//   - https://learn.microsoft.com/dotnet/api/system.collections.ienumerator.reset#remarks;
	//   - https://learn.microsoft.com/dotnet/api/system.collections.ienumerator#remarks.
	//
	// [Reset]: https://learn.microsoft.com/dotnet/api/system.collections.ienumerator.reset
	Reset()
}

Enumerator supports a simple iteration over a generic sequence. T - the type of objects to enumerate.

func CloneEmpty

func CloneEmpty[T any](enr Enumerator[T]) Enumerator[T]

CloneEmpty creates a new empty Enumerator of the same type as 'enr'.

type Grouping

type Grouping[Key, Element any] struct {
	// contains filtered or unexported fields
}

Grouping represents a collection of objects that have a common key.

func (*Grouping[Key, Element]) Count added in v2.4.0

func (gr *Grouping[Key, Element]) Count() int

Count returns the number of elements in the Grouping.

func (*Grouping[Key, Element]) GetEnumerator

func (gr *Grouping[Key, Element]) GetEnumerator() Enumerator[Element]

GetEnumerator returns an Enumerator that iterates through the Grouping's collection.

GetEnumerator implements the Enumerable interface.

func (*Grouping[Key, Element]) Key

func (gr *Grouping[Key, Element]) Key() Key

Key gets the key of the Grouping.

func (*Grouping[Key, Element]) String

func (gr *Grouping[Key, Element]) String() string

String implements the fmt.Stringer interface.

func (*Grouping[Key, Element]) Values added in v2.4.0

func (gr *Grouping[Key, Element]) Values() []Element

Values returns the values of the Grouping.

type Itemer

type Itemer[T any] interface {
	// Item returns the element at the specified index in the sequence.
	Item(int) T
}

Itemer is the interface that wraps the Item method.

type Lookup

type Lookup[Key, Element any] struct {

	// KeyEq is an equaler for groupings' keys
	KeyEq collate.Equaler[Key]
	// contains filtered or unexported fields
}

Lookup represents a collection of keys each mapped to one or more values.

func ToLookup

func ToLookup[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) (*Lookup[Key, Source], error)

ToLookup creates a Lookup from an Enumerable according to a specified key selector function.

collate.DeepEqualer is used to compare keys. 'source' is enumerated immediately.

func ToLookupEq

func ToLookupEq[Source, Key any](source Enumerable[Source], keySelector func(Source) Key, equaler collate.Equaler[Key]) (*Lookup[Key, Source], error)

ToLookupEq creates a Lookup from an Enumerable according to a specified key selector function and a key equaler.

If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func ToLookupEqMust

func ToLookupEqMust[Source, Key any](source Enumerable[Source], keySelector func(Source) Key, equaler collate.Equaler[Key]) *Lookup[Key, Source]

ToLookupEqMust is like ToLookupEq but panics in case of error.

func ToLookupMust

func ToLookupMust[Source, Key any](source Enumerable[Source], keySelector func(Source) Key) *Lookup[Key, Source]

ToLookupMust is like ToLookup but panics in case of error.

func ToLookupSel

func ToLookupSel[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) (*Lookup[Key, Element], error)

ToLookupSel creates a Lookup from an Enumerable according to specified key selector and element selector functions.

collate.DeepEqualer is used to compare keys. 'source' is enumerated immediately.

func ToLookupSelEq

func ToLookupSelEq[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element, equaler collate.Equaler[Key]) (*Lookup[Key, Element], error)

ToLookupSelEq creates a Lookup from an Enumerable according to a specified key selector function, an element selector function and a key equaler.

If 'equaler' is nil collate.DeepEqualer is used. 'source' is enumerated immediately.

func ToLookupSelEqMust

func ToLookupSelEqMust[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element, equaler collate.Equaler[Key]) *Lookup[Key, Element]

ToLookupSelEqMust is like ToLookupSelEq but panics in case of error.

func ToLookupSelMust

func ToLookupSelMust[Source, Key, Element any](source Enumerable[Source],
	keySelector func(Source) Key, elementSelector func(Source) Element) *Lookup[Key, Element]

ToLookupSelMust is like ToLookupSel but panics in case of error.

Example

see LookupExample from Lookup Class help https://learn.microsoft.com/dotnet/api/system.linq.Lookup-2#examples

// Create a list of Packages to put into a Lookup data structure.
packages := []Package{
	{Company: "Coho Vineyard", Weight: 25.2, TrackingNumber: 89453312},
	{Company: "Lucerne Publishing", Weight: 18.7, TrackingNumber: 89112755},
	{Company: "Wingtip Toys", Weight: 6.0, TrackingNumber: 299456122},
	{Company: "Contoso Pharmaceuticals", Weight: 9.3, TrackingNumber: 670053128},
	{Company: "Wide World Importers", Weight: 33.8, TrackingNumber: 4665518773},
}
// Create a Lookup to organize the packages.
// Use the first character of Company as the key value.
// Select Company appended to TrackingNumber for each element value in the Lookup.
lookup := ToLookupSelMust(
	NewEnSliceEn(packages...),
	func(p Package) rune {
		return []rune(p.Company)[0]
	},
	func(p Package) string {
		return fmt.Sprintf("%s %d", p.Company, p.TrackingNumber)
	},
)

// Iterate through each Grouping in the Lookup and output the contents.
enrLookup := lookup.GetEnumerator()
for enrLookup.MoveNext() {
	packageGroup := enrLookup.Current()
	// Print the key value of the Grouping.
	fmt.Println(string(packageGroup.Key()))
	// Iterate through each value in the Grouping and print its value.
	enGr := packageGroup.GetEnumerator()
	for enGr.MoveNext() {
		str := enGr.Current()
		fmt.Printf("    %s\n", str)
	}
}

// Get the number of key-collection pairs in the Lookup.
count := lookup.Count()
fmt.Printf("\n%d\n", count)

// Select a collection of Packages by indexing directly into the Lookup.
cgroup := lookup.Item('C')
// Output the results.
fmt.Println("\nPackages that have a key of 'C'")
enrCgroup := cgroup.GetEnumerator()
for enrCgroup.MoveNext() {
	str := enrCgroup.Current()
	fmt.Println(str)
}

// Determine if there is a key with the value 'G' in the Lookup.
hasG := lookup.Contains('G')
fmt.Printf("\n%t\n", hasG)
Output:

C
    Coho Vineyard 89453312
    Contoso Pharmaceuticals 670053128
L
    Lucerne Publishing 89112755
W
    Wingtip Toys 299456122
    Wide World Importers 4665518773

3

Packages that have a key of 'C'
Coho Vineyard 89453312
Contoso Pharmaceuticals 670053128

false

func (*Lookup[Key, Element]) Add added in v2.4.0

func (lk *Lookup[Key, Element]) Add(key Key, el Element)

Add adds element 'el' with specified 'key' to 'lk'

func (*Lookup[Key, Element]) Contains

func (lk *Lookup[Key, Element]) Contains(key Key) bool

Contains determines whether a specified key is in the Lookup.

func (*Lookup[Key, Element]) Count

func (lk *Lookup[Key, Element]) Count() int

Count gets the number of key/value collection pairs in the Lookup.

func (*Lookup[Key, Element]) EqualTo added in v2.0.3

func (lk *Lookup[Key, Element]) EqualTo(lk2 *Lookup[Key, Element]) bool

EqualTo determines whether the current Lookup is equal to a specified Lookup.

Keys equality comparers do not participate in equality verification, since non-nil funcs are always not deeply equal.

func (*Lookup[Key, Element]) GetEnumerator

func (lk *Lookup[Key, Element]) GetEnumerator() Enumerator[Grouping[Key, Element]]

GetEnumerator returns an Enumerator that iterates through the Lookup.

GetEnumerator implements the Enumerable interface.

func (*Lookup[Key, Element]) Item

func (lk *Lookup[Key, Element]) Item(key Key) Enumerable[Element]

Item gets the collection of values indexed by a specified key.

func (*Lookup[Key, Element]) ItemSlice

func (lk *Lookup[Key, Element]) ItemSlice(key Key) []Element

ItemSlice returns a slice containing values.

func (*Lookup[Key, Element]) Slice

func (lk *Lookup[Key, Element]) Slice() []Grouping[Key, Element]

Slice returns a slice containing the Lookup's contents.

func (*Lookup[Key, Element]) String

func (lk *Lookup[Key, Element]) String() string

String implements the fmt.Stringer interface.

type OrderedEnumerable

type OrderedEnumerable[Element any] struct {
	// contains filtered or unexported fields
}

OrderedEnumerable represents a sorted sequence.

func OrderBy

func OrderBy[Source constraints.Ordered](source Enumerable[Source]) (*OrderedEnumerable[Source], error)

OrderBy sorts the elements of a sequence in ascending order.

func OrderByDesc

func OrderByDesc[Source constraints.Ordered](source Enumerable[Source]) (*OrderedEnumerable[Source], error)

OrderByDesc sorts the elements of a sequence in descending order.

func OrderByDescKey added in v2.4.0

func OrderByDescKey[Source any, Key constraints.Ordered](source Enumerable[Source],
	keySelector func(Source) Key) (*OrderedEnumerable[Source], error)

OrderByDescKey sorts the elements of a sequence in descending order according to a key.

func OrderByDescKeyLs added in v2.4.0

func OrderByDescKeyLs[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error)

OrderByDescKeyLs sorts the elements of a sequence in descending order of keys using a specified lesser.

func OrderByDescKeyLsMust added in v2.4.0

func OrderByDescKeyLsMust[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source]

OrderByDescKeyLsMust is like OrderByDescKeyLs but panics in case of error.

func OrderByDescKeyMust added in v2.4.0

func OrderByDescKeyMust[Source any, Key constraints.Ordered](source Enumerable[Source],
	keySelector func(Source) Key) *OrderedEnumerable[Source]

OrderByDescKeyMust is like OrderByDescKey but panics in case of error.

Example
fmt.Println(ToStringDef[string](
	OrderByDescKeyMust(
		NewEnSliceEn("zero", "one", "two", "three", "four", "five"),
		func(s string) int { return len(s) },
	),
))
Output:

[three zero four five one two]

func OrderByDescLs

func OrderByDescLs[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error)

OrderByDescLs sorts the elements of a sequence in descending order using a specified lesser.

func OrderByDescLsMust

func OrderByDescLsMust[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source]

OrderByDescLsMust is like OrderByDescLs but panics in case of error.

Example

see OrderByDescendingEx1 example from Enumerable.OrderByDescending help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderbydescending

decimals := []float64{6.2, 8.3, 0.5, 1.3, 6.3, 9.7}
var ls collate.Lesser[float64] = collate.LesserFunc[float64](
	func(f1, f2 float64) bool {
		_, fr1 := math.Modf(f1)
		_, fr2 := math.Modf(f2)
		if math.Abs(fr1-fr2) < 0.001 {
			return f1 < f2
		}
		return fr1 < fr2
	},
)
query := OrderByDescLsMust(
	NewEnSliceEn(decimals...),
	ls,
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	num := enr.Current()
	fmt.Println(num)
}
Output:

9.7
0.5
8.3
6.3
1.3
6.2

func OrderByDescMust

func OrderByDescMust[Source constraints.Ordered](source Enumerable[Source]) *OrderedEnumerable[Source]

OrderByDescMust is like OrderByDesc but panics in case of error.

func OrderByKey

func OrderByKey[Source any, Key constraints.Ordered](source Enumerable[Source],
	keySelector func(Source) Key) (*OrderedEnumerable[Source], error)

OrderByKey sorts the elements of a sequence in ascending order according to a key.

func OrderByKeyLs

func OrderByKeyLs[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error)

OrderByKeyLs sorts the elements of a sequence in ascending order of keys using a specified lesser.

func OrderByKeyLsMust

func OrderByKeyLsMust[Source, Key any](source Enumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source]

OrderByKeyLsMust is like OrderByKeyLs but panics in case of error.

func OrderByKeyMust

func OrderByKeyMust[Source any, Key constraints.Ordered](source Enumerable[Source],
	keySelector func(Source) Key) *OrderedEnumerable[Source]

OrderByKeyMust is like OrderByKey but panics in case of error.

func OrderByLs

func OrderByLs[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error)

OrderByLs sorts the elements of a sequence in ascending order using a specified lesser.

func OrderByLsMust

func OrderByLsMust[Source any](source Enumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source]

OrderByLsMust is like OrderByLs but panics in case of error.

Example

see OrderByEx1 example from Enumerable.OrderBy help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.orderby

pets := []Pet{
	{Name: "Barley", Age: 8},
	{Name: "Boots", Age: 4},
	{Name: "Whiskers", Age: 1},
}
var ls collate.Lesser[Pet] = collate.LesserFunc[Pet](func(p1, p2 Pet) bool { return p1.Age < p2.Age })
query := OrderByLsMust(
	NewEnSliceEn(pets...),
	ls,
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	pet := enr.Current()
	fmt.Printf("%s - %d\n", pet.Name, pet.Age)
}
Output:

Whiskers - 1
Boots - 4
Barley - 8

func OrderByMust

func OrderByMust[Source constraints.Ordered](source Enumerable[Source]) *OrderedEnumerable[Source]

OrderByMust is like OrderBy but panics in case of error.

Example
fmt.Println(ToStringDef[string](
	OrderByMust(
		NewEnSliceEn("zero", "one", "two", "three", "four", "five"),
	),
))
Output:

[five four one three two zero]

func ThenBy

func ThenBy[Source constraints.Ordered](source *OrderedEnumerable[Source]) (*OrderedEnumerable[Source], error)

ThenBy performs a subsequent ordering of the elements in a sequence in ascending order.

func ThenByDesc

func ThenByDesc[Source constraints.Ordered](source *OrderedEnumerable[Source]) (*OrderedEnumerable[Source], error)

ThenByDesc performs a subsequent ordering of the elements in a sequence in descending order.

func ThenByDescKey added in v2.4.0

func ThenByDescKey[Source any, Key constraints.Ordered](source *OrderedEnumerable[Source],
	keySelector func(Source) Key) (*OrderedEnumerable[Source], error)

ThenByDescKey performs a subsequent ordering of the elements in a sequence in descending order according to a key.

func ThenByDescKeyLs added in v2.4.0

func ThenByDescKeyLs[Source, Key any](source *OrderedEnumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error)

ThenByDescKeyLs performs a subsequent ordering of the elements in a sequence in descending order according to a key using a specified lesser.

func ThenByDescKeyLsMust added in v2.4.0

func ThenByDescKeyLsMust[Source, Key any](source *OrderedEnumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source]

ThenByDescKeyLsMust is like ThenByDescKeyLs but panics in case of error.

func ThenByDescKeyMust added in v2.4.0

func ThenByDescKeyMust[Source any, Key constraints.Ordered](source *OrderedEnumerable[Source],
	keySelector func(Source) Key) *OrderedEnumerable[Source]

ThenByDescKeyMust is like ThenByDescKey but panics in case of error.

func ThenByDescLs

func ThenByDescLs[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error)

ThenByDescLs performs a subsequent ordering of the elements in a sequence in descending order using a specified lesser.

func ThenByDescLsMust

func ThenByDescLsMust[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source]

ThenByDescLsMust is like ThenByDescLs but panics in case of error.

Example

see ThenByDescendingEx1 example from Enumerable.ThenByDescending help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenbydescending

fruits := []string{"apPLe", "baNanA", "apple", "APple", "orange", "BAnana", "ORANGE", "apPLE"}
// Sort the strings first ascending by their length and then descending using a custom case insensitive comparer.
query := ThenByDescLsMust(
	OrderByKeyMust(
		NewEnSliceEn(fruits...),
		func(fruit string) int { return len(fruit) },
	),
	collate.CaseInsensitiveLesser,
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	fruit := enr.Current()
	fmt.Println(fruit)
}
Output:

apPLe
apple
APple
apPLE
orange
ORANGE
baNanA
BAnana

func ThenByDescMust

func ThenByDescMust[Source constraints.Ordered](source *OrderedEnumerable[Source]) *OrderedEnumerable[Source]

ThenByDescMust is like ThenByDesc but panics in case of error.

func ThenByKey

func ThenByKey[Source any, Key constraints.Ordered](source *OrderedEnumerable[Source],
	keySelector func(Source) Key) (*OrderedEnumerable[Source], error)

ThenByKey performs a subsequent ordering of the elements in a sequence in ascending order according to a key.

func ThenByKeyLs

func ThenByKeyLs[Source, Key any](source *OrderedEnumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) (*OrderedEnumerable[Source], error)

ThenByKeyLs performs a subsequent ordering of the elements in a sequence in ascending order according to a key using a specified lesser.

func ThenByKeyLsMust

func ThenByKeyLsMust[Source, Key any](source *OrderedEnumerable[Source],
	keySelector func(Source) Key, lesser collate.Lesser[Key]) *OrderedEnumerable[Source]

ThenByKeyLsMust is like ThenByKeyLs but panics in case of error.

func ThenByKeyMust

func ThenByKeyMust[Source any, Key constraints.Ordered](source *OrderedEnumerable[Source],
	keySelector func(Source) Key) *OrderedEnumerable[Source]

ThenByKeyMust is like ThenByKey but panics in case of error.

func ThenByLs

func ThenByLs[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) (*OrderedEnumerable[Source], error)

ThenByLs performs a subsequent ordering of the elements in a sequence in ascending order using a specified lesser.

func ThenByLsMust

func ThenByLsMust[Source any](source *OrderedEnumerable[Source], lesser collate.Lesser[Source]) *OrderedEnumerable[Source]

ThenByLsMust is like ThenByLs but panics in case of error.

func ThenByMust

func ThenByMust[Source constraints.Ordered](source *OrderedEnumerable[Source]) *OrderedEnumerable[Source]

ThenByMust is like ThenBy but panics in case of error.

Example

see the example from Enumerable.ThenBy help https://learn.microsoft.com/dotnet/api/system.linq.enumerable.thenby

fruits := []string{"grape", "passionfruit", "banana", "mango", "orange", "raspberry", "apple", "blueberry"}
// Sort the strings first by their length and then alphabetically.
query := ThenByMust(
	OrderByKeyMust(
		NewEnSliceEn(fruits...),
		func(fruit string) int { return len(fruit) },
	),
)
enr := query.GetEnumerator()
for enr.MoveNext() {
	fruit := enr.Current()
	fmt.Println(fruit)
}
Output:

apple
grape
mango
banana
orange
blueberry
raspberry
passionfruit

func (*OrderedEnumerable[Element]) GetEnumerator

func (oe *OrderedEnumerable[Element]) GetEnumerator() Enumerator[Element]

GetEnumerator converts OrderedEnumerable to sorted sequence using sort.SliceStable for sorting.

GetEnumerator implements the Enumerable interface.

type Slicer

type Slicer[T any] interface {
	// Slice returns the sequence contents as a slice.
	Slice() []T
}

Slicer is the interface that wraps the Slice method.

Directories

Path Synopsis
Package slice implements .NET's [LINQ to Objects] for slices.
Package slice implements .NET's [LINQ to Objects] for slices.

Jump to

Keyboard shortcuts

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