xslices

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2025 License: MIT Imports: 2 Imported by: 0

README

Go Reference GitHub go.mod Go version MIT License

xslices

An extension to the standard Go slices package.

Install:

go get -u github.com/rodrigocfd/xslices

Documentation:

License

Licensed under MIT license, see LICENSE.md for details.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendN

func AppendN[S ~[]E, E any](src S, n int, elem E) S

AppendN appends n copies of elem to src, returning the new slice. If n is negative, AppendN panics.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{4, 5, 6}
	nums = xslices.AppendN(nums, 3, 900)
	fmt.Println(nums)
}
Output:

[4 5 6 900 900 900]

func CollectFallible added in v0.1.1

func CollectFallible[E any](seq iter.Seq2[E, error]) ([]E, error)

CollectFallible is similar to slices.Collect, but it collects only the first value of each iter.Seq2 into a new slice. The second returned value – the error – will be nil.

However, if at any point of the iteration, the second value – the error – is not nil, the iteration stops and it returns nil and the error.

In other words: CollectFallible returns a new slice with the first values of iter.Seq2, but if there is an error, it stops the iteration and returns the error.

Example
package main

import (
	"errors"
	"fmt"
	"iter"

	"github.com/rodrigocfd/xslices"
)

func main() {
	generateNums := func() iter.Seq2[int, error] {
		return func(yield func(int, error) bool) {
			nums := []int{44, 45, 46}
			errs := []error{nil, errors.New("oops!"), nil}

			for i := range len(nums) {
				if !yield(nums[i], errs[i]) {
					return
				}
			}
		}
	}

	numsErrs := generateNums()
	nums, err := xslices.CollectFallible(numsErrs)
	fmt.Println(nums, err)
}
Output:

[] oops!

func CollectFirst

func CollectFirst[A, B any](seq iter.Seq2[A, B]) []A

CollectFirst is similar to slices.Collect, but it collects only the first value of each iter.Seq2 into a new slice. The second value is discarded.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{44, 45, 46}
	all := slices.All(nums)

	indexes := xslices.CollectFirst(all)

	fmt.Println(indexes)
}
Output:

[0 1 2]

func CollectSecond

func CollectSecond[A, B any](seq iter.Seq2[A, B]) []B

CollectSecond is similar to slices.Collect, but it collects only the second value of each iter.Seq2 into a new slice. The first value is discarded.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{44, 45, 46}
	all := slices.All(nums)

	vals := xslices.CollectSecond(all)

	fmt.Println(vals)
}
Output:

[44 45 46]

func CollectUnzip added in v0.1.1

func CollectUnzip[A, B any](seq iter.Seq2[A, B]) ([]A, []B)

CollectUnzip is similar to slices.Collect, but it collects the first and second values of iter.Seq2 into two new separated slices.

Example
package main

import (
	"fmt"
	"slices"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{44, 45, 46}
	all := slices.All(nums)

	indexes, vals := xslices.CollectUnzip(all)
	fmt.Println(indexes, vals)
}
Output:

[0 1 2] [44 45 46]

func CountFunc

func CountFunc[E any](src []E, pred func(index int, elem E) bool) int

CountFunc calls pred for each element in src, and counts how many times pred returns true.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"abc", "yyy", "axx"}

	nStartWithA := xslices.CountFunc(strs, func(i int, s string) bool {
		return s[0] == 'a'
	})

	fmt.Println("How many start with a:", nStartWithA)
}
Output:

How many start with a: 2

func Every

func Every[E comparable](src []E, elem E) bool

Every returns true if all elements in src are equal to elem. The iteration stops at the first different element.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{3, 3, 3, 3}

	onlyThree := xslices.Every(nums, 3)

	fmt.Println("All elements are 3:", onlyThree)
}
Output:

All elements are 3: true

func EveryFunc

func EveryFunc[E any](src []E, pred func(index int, elem E) bool) bool

EveryFunc returns true if pred returns true for all elements in src. The iteration stops at the first return of false.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"abc", "ayy", "axx"}

	allStartWithA := xslices.EveryFunc(strs, func(i int, s string) bool {
		return s[0] == 'a'
	})

	fmt.Println("All strings start with a?", allStartWithA)
}
Output:

All strings start with a? true

func Filter

func Filter[E any](src []E, pred func(index int, elem E) bool) iter.Seq2[int, E]

Filter calls pred for each element in src. If pred returns true, the index and value of this element will be returned in the iter.Seq2.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"abc", "yyy", "axx"}

	seq := xslices.Filter(strs, func(i int, s string) bool {
		return s[0] == 'a'
	})

	for i, s := range seq {
		fmt.Printf("%d : %s starts with a\n", i, s)
	}
}
Output:

0 : abc starts with a
2 : axx starts with a

func Group

func Group[S ~[]E, E any, K comparable](src S, fun func(index int, elem E) K) map[K]S

Group runs fun for each element in src. The value returned by fun is used as the key for the resulting map, each key will contain a slice with the correspondent elements.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{-1, 8, 2, -9, 5}

	groups := xslices.Group(nums, func(i int, num int) string {
		if num < 0 {
			return "neg"
		}
		return "pos"
	})

	fmt.Println(groups)
}
Output:

map[neg:[-1 -9] pos:[8 2 5]]

func IndexFunc

func IndexFunc[E any](src []E, pred func(index int, elem E) bool) int

IndexFunc is similar to slices.Index, but pred also includes the element index.

IndexFunc returns the index of the first element to which pred returns true, or -1 if none.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"bbb", "axx", "app"}

	i := xslices.IndexFunc(strs, func(i int, s string) bool {
		return s[0] == 'a'
	})

	fmt.Println("Index of first string start with a:", i)
}
Output:

Index of first string start with a: 1

func LastIndex

func LastIndex[E comparable](src []E, elem E) int

LastIndex returns the index of the last occurrence of elem in src, or -1 if not present.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{55, 10, 10, 9, 33}

	fmt.Println(xslices.LastIndex(nums, 10))
	fmt.Println(xslices.LastIndex(nums, 9))
}
Output:

2
3

func LastIndexFunc

func LastIndexFunc[E any](src []E, pred func(index int, elem E) bool) int

LastIndexFunc returns the index of the last element to which pred returns true.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"abc", "axx", "yyy"}

	i := xslices.LastIndexFunc(strs, func(i int, s string) bool {
		return s[0] == 'a'
	})

	fmt.Println("Index of last string start with a:", i)
}
Output:

Index of last string start with a: 1

func Map

func Map[E, R any](src []E, fun func(index int, elem E) R) []R

Map returns a new slice with each element E in src mapped into a new element R, according to fun.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	strs := []string{"abc", "xy", "1234"}

	lengths := xslices.Map(strs, func(index int, s string) int {
		return len(s)
	})

	fmt.Println(lengths)
}
Output:

[3 2 4]

func Reduce

func Reduce[E, R any](src []E, initVal R, fun func(acc R, index int, elem E) R) R

Reduce calls fun for the first element in src, passing initVal in the acc argument. Then it calls fun for each subsequent element in src, passing the previously returned value in the acc argument.

The final result of running fun across all elements in src is a single value.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	runes := []rune{'x', 'y', 'z'}
	initStr := "aaa"

	finalStr := xslices.Reduce(runes, initStr, func(acc string, i int, r rune) string {
		return acc + string(r)
	})

	fmt.Println(finalStr)
}
Output:

aaaxyz

func RemoveDuplicates

func RemoveDuplicates[S ~[]E, E comparable](src S) S

RemoveDuplicates removes all the duplicated elements in src. In the case of duplicates, the first element is kept, the subsequent ones are removed.

The returned slice points to the same memory of the original src, that is, no new allocation is made.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{1, 1, 2, 3, 3, 4}
	nums = xslices.RemoveDuplicates(nums)
	fmt.Println(nums)
}
Output:

[1 2 3 4]

func ShallowClone

func ShallowClone[S ~[]E, E any](src S) S

ShallowClone returns a newly allocated slice with each element copied.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{30, 40, 50}

	cloned := xslices.ShallowClone(nums)

	fmt.Println(cloned)
}
Output:

[30 40 50]

func Split

func Split[S ~[]E, E comparable](src S, sep E) iter.Seq[S]

Split returns an iter.Seq with subslices over the original src, separated by sep.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{11, 12, 333, 45, 333, 20, 21}

	for block := range xslices.Split(nums, 333) {
		fmt.Println(block)
	}
}
Output:

[11 12]
[45]
[20 21]

func Trim

func Trim[S ~[]E, E comparable](src S, elem E) S

Trim returns a subslice without the first and last elements which contiguously match elem.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{9, 9, 1, 2, 3, 9}

	noNine := xslices.Trim(nums, 9)

	fmt.Println(noNine)
}
Output:

[1 2 3]

func TrimLeft

func TrimLeft[S ~[]E, E comparable](src S, elem E) S

TrimLeft returns a subslice without the first elements which contiguously match elem.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{4, 4, 4, 3, 2, 8}

	noFour := xslices.TrimLeft(nums, 4)

	fmt.Println(noFour)
}
Output:

[3 2 8]

func TrimRight

func TrimRight[S ~[]E, E comparable](src S, elem E) S

TrimRight returns a subslice without the last elements which contiguously match elem.

Example
package main

import (
	"fmt"

	"github.com/rodrigocfd/xslices"
)

func main() {
	nums := []int{3, 5, 1, 7, 7}

	noSeven := xslices.TrimRight(nums, 7)

	fmt.Println(noSeven)
}
Output:

[3 5 1]

Types

This section is empty.

Jump to

Keyboard shortcuts

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