slicex

package
v0.4.4 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2023 License: MIT Imports: 7 Imported by: 7

Documentation

Overview

Additional functions for playing with slices and reduce mistakes.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func At

func At[S ~[]T, T any](s S, i int) (T, bool)

Returns the item from the slice according to the given index.

If `i < 0`, it returns the item counting from the end of the slice.

If the given index doesn't contain a value (boundary exceeded), the zero-value of the given type and `false` will be returned.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	v1, ok1 := slicex.At(list, 3)
	v2, ok2 := slicex.At(list, -3)
	v3, ok3 := slicex.At(list, 10)

	fmt.Println(v1, ok1)
	fmt.Println(v2, ok2)
	fmt.Println(v3, ok3)
}
Output:

3 true
7 true
0 false
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	v1, ok1 := slicex.At(list, 1)
	v2, ok2 := slicex.At(list, -2)
	v3, ok3 := slicex.At(list, 4)

	fmt.Println(v1, ok1)
	fmt.Println(v2, ok2)
	fmt.Printf("%#v %v\n", v3, ok3)
}
Output:

World true
Hi true
"" false

func Chunk

func Chunk[S ~[]T, T any](original S, length int) []S

Breaks the original slice into smaller chunks according to the given length.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	list2 := slicex.Chunk(list1, 2)
	list3 := slicex.Chunk(list1, 3)

	fmt.Println(list2)
	fmt.Println(list3)
}
Output:

[[0 1] [2 3] [4 5] [6 7] [8 9]]
[[0 1 2] [3 4 5] [6 7 8] [9]]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World", "Hi", "A-yon"}
	list2 := slicex.Chunk(list1, 2)
	list3 := slicex.Chunk(list1, 3)

	fmt.Println(list2)
	fmt.Println(list3)
}
Output:

[[Hello World] [Hi A-yon]]
[[Hello World Hi] [A-yon]]

func CompareItems

func CompareItems[T any](a, b T) int

This function is used as the compare function for sorting functions.

func Concat

func Concat[S ~[]T, T any](sources ...S) S

Merges two or more slices into one and returns the new slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2}
	list2 := []int{3, 4, 5}
	list3 := []int{6, 7, 8}
	list4 := []int{9}
	list5 := slicex.Concat(list1, list2, list3, list4)

	fmt.Println(list5)
}
Output:

[0 1 2 3 4 5 6 7 8 9]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := []string{"Hi", "A-yon"}
	list3 := slicex.Concat(list1, list2)

	fmt.Println(list3)
}
Output:

[Hello World Hi A-yon]

func Count

func Count[S ~[]T, T comparable](s S, item T) int

Counts the occurrence of the item against the given slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0}
	count1 := slicex.Count(list, 3)
	count2 := slicex.Count(list, 10)

	fmt.Println(count1)
	fmt.Println(count2)
}
Output:

2
0
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hello", "A-yon"}
	count1 := slicex.Count(list, "Hello")
	count2 := slicex.Count(list, "Hi")

	fmt.Println(count1)
	fmt.Println(count2)
}
Output:

2
0

func Diff

func Diff[S ~[]T, T comparable](first S, others ...S) S

Finds all the items presented in the first slice but are missing in the others.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5}
	list2 := []int{2, 3, 4, 5, 6, 7}
	list3 := slicex.Diff(list1, list2)

	fmt.Println(list3)
}
Output:

[0 1]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := []string{"Hi", "World"}
	list3 := slicex.Diff(list1, list2)

	fmt.Println(list3)
}
Output:

[Hello]

func Every

func Every[S ~[]T, T any](s S, fn func(item T, idx int) bool) bool

Tests whether all items in the slice pass the test implemented by the provided function.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	ok1 := slicex.Every(list, func(item int, _ int) bool { return item < 3 })
	ok2 := slicex.Every(list, func(item int, _ int) bool { return item < 2 })

	fmt.Println(ok1)
	fmt.Println(ok2)
}
Output:

true
false
Example (String)
package main

import (
	"fmt"
	"strings"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	ok1 := slicex.Every(list1, func(item string, _ int) bool { return strings.Contains(item, "o") })
	ok2 := slicex.Every(list1, func(item string, _ int) bool { return strings.Contains(item, "H") })

	fmt.Println(ok1)
	fmt.Println(ok2)
}
Output:

true
false

func Filter

func Filter[S ~[]T, T any](original S, fn func(item T, idx int) bool) S

Creates a shallow copy of a portion of a given slice, filtered down to just the items from the given slice that pass the test implemented by the provided function.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	list2 := slicex.Filter(list1, func(item int, _ int) bool { return item%2 == 0 })

	fmt.Println(list2)
}
Output:

[0 2 4 6 8]
Example (String)
package main

import (
	"fmt"
	"strings"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World", "Hi", "A-yon"}
	list2 := slicex.Filter(list1, func(item string, _ int) bool { return strings.HasPrefix(item, "H") })

	fmt.Println(list2)
}
Output:

[Hello Hi]

func Find

func Find[S ~[]T, T any](s S, fn func(item T, idx int) bool) (T, bool)

Returns the first item in the provided slice that satisfies the provided testing function.

If no value satisfies the testing function, the zero-value of the given type and `false` will be returned.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	value1, ok1 := slicex.Find(list, func(item int, _ int) bool { return item >= 5 })
	value2, ok2 := slicex.Find(list, func(item int, _ int) bool { return item >= 10 })

	fmt.Println(value1, ok1)
	fmt.Println(value2, ok2)
}
Output:

5 true
0 false
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	value1, ok1 := slicex.Find(list, func(item string, idx int) bool { return idx == 2 })
	value2, ok2 := slicex.Find(list, func(item string, idx int) bool { return idx == 5 })

	fmt.Println(value1, ok1)
	fmt.Printf("%#v %v\n", value2, ok2)
}
Output:

Hi true
"" false

func FindIndex

func FindIndex[S ~[]T, T any](s S, fn func(item T, idx int) bool) int

Returns the index of the first item in the slice that satisfies the provided testing function. If no item satisfies the testing function, -1 is returned.

This function is similar to the `slices.IndexFunc()` from the standard library.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	idx1 := slicex.FindIndex(list, func(item int, _ int) bool { return item >= 5 })
	idx2 := slicex.FindIndex(list, func(item int, _ int) bool { return item >= 10 })

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

5
-1
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	idx1 := slicex.FindLastIndex(list, func(item string, idx int) bool { return item == "Hi" })
	idx2 := slicex.FindLastIndex(list, func(item string, idx int) bool { return item == "Haha" })

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

2
-1

func FindLast

func FindLast[S ~[]T, T any](s S, fn func(item T, idx int) bool) (T, bool)

Iterates the slice in reverse order and returns the value of the first item that satisfies the provided testing function.

If no item satisfies the testing function, the zero-value of the given type and `false` will be returned.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	value1, ok1 := slicex.FindLast(list, func(item int, _ int) bool { return item >= 5 })
	value2, ok2 := slicex.FindLast(list, func(item int, _ int) bool { return item >= 10 })

	fmt.Println(value1, ok1)
	fmt.Println(value2, ok2)
}
Output:

9 true
0 false
Example (String)
package main

import (
	"fmt"
	"strings"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	value1, ok1 := slicex.FindLast(list, func(item string, _ int) bool {
		return strings.HasPrefix(item, "H")
	})
	value2, ok2 := slicex.FindLast(list, func(item string, _ int) bool {
		return strings.HasPrefix(item, "o")
	})

	fmt.Println(value1, ok1)
	fmt.Printf("%#v %v\n", value2, ok2)
}
Output:

Hi true
"" false

func FindLastIndex

func FindLastIndex[S ~[]T, T any](s S, fn func(item T, idx int) bool) int

Iterates the slice in reverse order and returns the index of the first item that satisfies the provided testing function. If no item satisfies the testing function, -1 is returned.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	idx1 := slicex.FindLastIndex(list, func(item int, _ int) bool { return item >= 5 })
	idx2 := slicex.FindLastIndex(list, func(item int, _ int) bool { return item >= 10 })

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

9
-1
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hello", "A-yon"}
	idx1 := slicex.FindLastIndex(list, func(item string, idx int) bool { return item == "Hello" })
	idx2 := slicex.FindLastIndex(list, func(item string, idx int) bool { return item == "Haha" })

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

2
-1

func Flat

func Flat[S ~[]T, T any](original []S) S

Creates a new slice with all sub-slice items concatenated into it.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := [][]int{{0, 1, 2, 3, 4}, {5, 6, 7, 8, 9}}
	list2 := slicex.Flat(list1)

	fmt.Println(list2)
}
Output:

[0 1 2 3 4 5 6 7 8 9]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := [][]string{{"Hello", "World"}, {"Hi", "A-yon"}}
	list2 := slicex.Flat(list1)

	fmt.Println(list2)
}
Output:

[Hello World Hi A-yon]

func ForEach added in v0.3.0

func ForEach[S ~[]T, T any](s S, fn func(item T, idx int))

Executes a provided function once for each slice item.

This function adds a closure context around each item looped, may be useful for preventing variable pollution.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2}

	slicex.ForEach(list1, func(item int, _ int) {
		fmt.Println(item)
	})
}
Output:

0
1
2
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}

	slicex.ForEach(list1, func(item string, _ int) {
		fmt.Println(item)
	})
}
Output:

Hello
World

func GroupBy

func GroupBy[S ~[]T, T ~map[K1]V, K1 comparable, V any, K2 comparable](
	items S,
	fn func(item T, idx int) K2,
) map[K2]S

Groups the items of the given slice according to the comparable values returned by a provided callback function. The returned map has separate properties for each group, containing slices with the items in the group.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []map[string]string{
		{
			"group": "world",
			"tag":   "A",
		},
		{
			"group": "room",
			"tag":   "B",
		},
		{
			"group": "room",
			"tag":   "C",
		},
	}
	record := slicex.GroupBy(list, func(item map[string]string, _ int) string {
		return item["group"]
	})

	fmt.Println(record)
}
Output:

map[room:[map[group:room tag:B] map[group:room tag:C]] world:[map[group:world tag:A]]]

func Intersect

func Intersect[S ~[]T, T comparable](sources ...S) S

Creates a slice containing the items which are presented in all the sources, duplicated items are removed.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5}
	list2 := []int{2, 3, 4, 5, 6, 7}
	list3 := slicex.Intersect(list1, list2)

	fmt.Println(list3)
}
Output:

[2 3 4 5]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := []string{"Hi", "World"}
	list3 := slicex.Intersect(list1, list2)

	fmt.Println(list3)
}
Output:

[World]

func Join

func Join[S ~[]T, T any](s S, sep string) string

Creates and returns a string by concatenating all of the items in the slice, separated by the specified separator string.

Example (Any)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []any{"Hello", 1, 2.0, map[string]uint8{"foo": 1}, nil}
	str1 := slicex.Join(list, ", ")
	str2 := slicex.Join(list, " | ")

	fmt.Println(str1)
	fmt.Println(str2)
}
Output:

Hello, 1, 2, map[foo:1], <nil>
Hello | 1 | 2 | map[foo:1] | <nil>
Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	str1 := slicex.Join(list, ",")
	str2 := slicex.Join(list, " ")

	fmt.Println(str1)
	fmt.Println(str2)
}
Output:

0,1,2,3,4,5,6,7,8,9
0 1 2 3 4 5 6 7 8 9
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	str1 := slicex.Join(list, ", ")
	str2 := slicex.Join(list, " | ")

	fmt.Println(str1)
	fmt.Println(str2)
}
Output:

Hello, World, Hi, A-yon
Hello | World | Hi | A-yon

func LastIndex

func LastIndex[S ~[]T, T comparable](s S, item T) int

Returns the last index at which a given item can be found in the slice, or -1 if it is not present. The slice is searched backwards.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0}
	idx1 := slicex.LastIndex(list, 3)
	idx2 := slicex.LastIndex(list, 10)

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

7
-1
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hello", "A-yon"}
	idx1 := slicex.LastIndex(list, "Hello")
	idx2 := slicex.LastIndex(list, "Hi")

	fmt.Println(idx1)
	fmt.Println(idx2)
}
Output:

2
-1

func Map

func Map[S ~[]T, T any, R any](original S, fn func(item T, idx int) R) []R

Creates a new slice populated with the results of calling a provided function on every item in the original slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2}
	list2 := slicex.Map(list1, func(item int, _ int) int { return item * 2 })

	fmt.Println(list2)
}
Output:

[0 2 4]
Example (String)
package main

import (
	"fmt"
	"strings"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := slicex.Map(list1, func(item string, _ int) string { return strings.ToUpper(item) })

	fmt.Println(list2)
}
Output:

[HELLO WORLD]

func OrderBy

func OrderBy[S ~[]T, T ~map[K]V, K comparable, V any](original S, key K, order string) S

Orders the items of the given slice according to the specified comparable `key` (whose value must either be of type int or string). `order` can be either `asc` or `desc`.

This function does not mutate the original slice but create a new one. However, if the `order` is malformed (not `asc` or `desc`), the function simply returns the original slice without ordering.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []map[string]any{
		{
			"id":  "world",
			"age": 53,
			"tag": "A",
		},
		{
			"id":  "ayon",
			"age": 28,
			"tag": "B",
		},
		{
			"id":  "claire",
			"age": 25,
			"tag": "B",
		},
	}
	list2 := slicex.OrderBy(list1, "age", "asc")
	list3 := slicex.OrderBy(list2, "age", "desc")
	list4 := slicex.OrderBy(list1, "id", "asc")
	list5 := slicex.OrderBy(list2, "tag", "desc")
	list6 := slicex.OrderBy(list1, "name", "desc") // this has no effect since key 'name' doesn't exist
	list7 := slicex.OrderBy(list1, "age", "foo")   // this has no effect since the `order` can only be either 'asc' or 'desc'

	fmt.Println(list2)
	fmt.Println(list3)
	fmt.Println(list4)
	fmt.Println(list5)
	fmt.Println(list6)
	fmt.Println(list7)
}
Output:

[map[age:25 id:claire tag:B] map[age:28 id:ayon tag:B] map[age:53 id:world tag:A]]
[map[age:53 id:world tag:A] map[age:28 id:ayon tag:B] map[age:25 id:claire tag:B]]
[map[age:28 id:ayon tag:B] map[age:25 id:claire tag:B] map[age:53 id:world tag:A]]
[map[age:28 id:ayon tag:B] map[age:25 id:claire tag:B] map[age:53 id:world tag:A]]
[map[age:53 id:world tag:A] map[age:28 id:ayon tag:B] map[age:25 id:claire tag:B]]
[map[age:53 id:world tag:A] map[age:28 id:ayon tag:B] map[age:25 id:claire tag:B]]

func Pop

func Pop[S ~[]T, T any](s *S) T

Removes the last item from the slice and returns that item.

This function mutates the input slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	item := slicex.Pop(&list)

	fmt.Println(list)
	fmt.Println(item)
}
Output:

[0 1]
2
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	item := slicex.Pop(&list)

	fmt.Println(list)
	fmt.Println(item)
}
Output:

[Hello World Hi]
A-yon

func Push

func Push[S ~[]T, T any](s *S, items ...T) int

Adds the specified items to the end of the slice and returns the new length of the slice.

This function mutates the input slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	length := slicex.Push(&list, 3, 4)

	fmt.Println(list)
	fmt.Println(length)
}
Output:

[0 1 2 3 4]
5
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World"}
	length := slicex.Push(&list, "Hi", "A-yon")

	fmt.Println(list)
	fmt.Println(length)
}
Output:

[Hello World Hi A-yon]
4

func Reduce

func Reduce[S ~[]T, T any, R any](s S, fn func(acc R, item T, idx int) R, acc R) R

Executes a user-supplied "reducer" callback function on each item of the slice, in order, passing in the return value from the calculation on the preceding item.

The reducer walks through the slice item-by-item, at each step adding the current item to the result from the previous step (this result is the running sum of all the previous steps) — until there are no more items to add.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	sum := slicex.Reduce(list, func(sum int, item int, _ int) int { return sum + item }, 0)

	fmt.Println(sum)
}
Output:

3
Example (Map)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []map[string]string{
		{
			"id":  "foo",
			"tag": "Hello",
		},
		{
			"id":  "bar",
			"tag": "World",
		},
	}
	record := slicex.Reduce(list, func(
		record map[string]map[string]string,
		item map[string]string,
		_ int,
	) map[string]map[string]string {
		record[item["id"]] = item
		return record
	}, map[string]map[string]string{})

	fmt.Println(record)
}
Output:

map[bar:map[id:bar tag:World] foo:map[id:foo tag:Hello]]

func Shift

func Shift[S ~[]T, T any](s *S) T

Removes the first item from the slice and returns that item.

This function mutates the input slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	item := slicex.Shift(&list)

	fmt.Println(list)
	fmt.Println(item)
}
Output:

[1 2]
0
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World", "Hi", "A-yon"}
	item := slicex.Shift(&list)

	fmt.Println(list)
	fmt.Println(item)
}
Output:

[World Hi A-yon]
Hello

func Shuffle

func Shuffle[S ~[]T, T any](s S)

Reorganizes the items in the given slice in random order.

This function mutate the input slice.

Example (Int)
package main

import (
	"fmt"
	"slices"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	list2 := slices.Clone(list1)
	list3 := slices.Clone(list1)

	slicex.Shuffle(list2) // now list2 is in any order
	slicex.Shuffle(list3) // now list3 is in any order

	fmt.Printf("list2(len: %d) != list1(len: %d): %v\n", len(list2), len(list1), !slices.Equal(list2, list1))
	fmt.Printf("list3(len: %d) != list1(len: %d): %v\n", len(list3), len(list1), !slices.Equal(list3, list1))
	fmt.Printf("list3(len: %d) != list2(len: %d): %v\n", len(list3), len(list2), !slices.Equal(list3, list2))
}
Output:

list2(len: 10) != list1(len: 10): true
list3(len: 10) != list1(len: 10): true
list3(len: 10) != list2(len: 10): true
Example (Sting)
package main

import (
	"fmt"
	"slices"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World", "Hi", "A-yon"}
	list2 := slices.Clone(list1)
	list3 := slices.Clone(list1)

	slicex.Shuffle(list2) // now list2 is in any order
	slicex.Shuffle(list3) // now list3 is in any order

	fmt.Printf("list2(len: %d) != list1(len: %d): %v\n", len(list2), len(list1), !slices.Equal(list2, list1))
	fmt.Printf("list3(len: %d) != list1(len: %d): %v\n", len(list3), len(list1), !slices.Equal(list3, list1))
	fmt.Printf("list3(len: %d) != list2(len: %d): %v\n", len(list3), len(list2), !slices.Equal(list3, list2))
}
Output:

list2(len: 4) != list1(len: 4): true
list3(len: 4) != list1(len: 4): true
list3(len: 4) != list2(len: 4): true

func Slice

func Slice[S ~[]T, T any](original S, start int, end int) S

Returns a shallow copy of a portion of the slice into a new slice selected from `start` to `end` (excluded).

If `start < 0`, it will be calculated as `len(original) + start`.

If `end < 0`, it will be calculated as `len(original) + end`.

Unlike the `[:]` syntax which creates a new slice that shares the same underlying array with the old slice, this function creates a new slice with new underlying array and copies data from the old one to the new one that prevent side effect when modifying them.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2}
	list2 := list1[0:2] // list2 shares the same underlying array with list1
	list3 := slicex.Slice(list1, 0, 2)
	list4 := slicex.Slice(list1, 0, -1)
	list5 := slicex.Slice(list1, -2, 4)
	list6 := slicex.Slice(list1, 3, 4)
	list7 := slicex.Slice(list1, 3, 2)

	list2[0] = 10  // modifying list2 will affect list1, and vice versa
	list3[0] = 100 // modifying list3 doesn't have side effect, and vice versa

	fmt.Println(list1)
	fmt.Println(list2)
	fmt.Println(list3)
	fmt.Println(list4)
	fmt.Println(list5)
	fmt.Println(list6)
	fmt.Println(list7)
}
Output:

[10 1 2]
[10 1]
[100 1]
[0 1]
[1 2]
[]
[]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World", "Hi", "A-yon"}
	list2 := list1[0:2] // list2 shares the same underlying array with list1
	list3 := slicex.Slice(list1, 0, 2)
	list4 := slicex.Slice(list1, 0, -2)

	list2[0] = "Hi"   // modifying list2 will affect list1, and vice versa
	list3[0] = "Hola" // modifying list3 doesn't have side effect, and vice versa

	fmt.Println(list1)
	fmt.Println(list2)
	fmt.Println(list3)
	fmt.Println(list4)
}
Output:

[Hi World Hi A-yon]
[Hi World]
[Hola World]
[Hello World]

func Some

func Some[S ~[]T, T any](s S, fn func(item T, idx int) bool) bool

Tests whether at least one item in the slice passes the test implemented by the provided function.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	ok1 := slicex.Some(list, func(item int, _ int) bool { return item < 1 })
	ok2 := slicex.Some(list, func(item int, _ int) bool { return item < 0 })

	fmt.Println(ok1)
	fmt.Println(ok2)
}
Output:

true
false
Example (String)
package main

import (
	"fmt"
	"strings"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	ok1 := slicex.Some(list1, func(item string, _ int) bool { return strings.Contains(item, "H") })
	ok2 := slicex.Some(list1, func(item string, _ int) bool { return strings.Contains(item, "i") })

	fmt.Println(ok1)
	fmt.Println(ok2)
}
Output:

true
false

func Split added in v0.3.2

func Split[S ~[]T, T comparable](original S, delimiter T) []S

Breaks the original slice into smaller chunks according to the given delimiter.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5, 4, 3, 2, 1}
	list2 := slicex.Split(list1, 2)
	list3 := slicex.Split(list1, 5)
	list4 := slicex.Split(list1, 1)

	fmt.Println(list2)
	fmt.Println(list3)
	fmt.Println(list4)
}
Output:

[[0 1] [3 4 5 4 3] [1]]
[[0 1 2 3 4] [4 3 2 1]]
[[0] [2 3 4 5 4 3 2] []]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"foo", "bar", "foo", "abc", "def", "foo", "bar"}
	list2 := slicex.Split(list1, "foo")
	list3 := slicex.Split(list1, "bar")

	fmt.Println(list2)
	fmt.Println(list3)
}
Output:

[[] [bar] [abc def] [bar]]
[[foo] [foo abc def foo] []]

func Union

func Union[S ~[]T, T comparable](sources ...S) S

Creates a new slice containing all the items from the given sources and remove the duplicated ones.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5}
	list2 := []int{2, 3, 4, 5, 6, 7}
	list3 := slicex.Union(list1, list2)
	list4 := slicex.Union(list1, list2, nil) // nil will be ignored

	fmt.Println(list3)
	fmt.Println(list4)
}
Output:

[0 1 2 3 4 5 6 7]
[0 1 2 3 4 5 6 7]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := []string{"Hi", "World"}
	list3 := slicex.Union(list1, list2)
	list4 := slicex.Union(list1, list2, nil) // nil will be ignored
	fmt.Println(list4)

	fmt.Println(list3)
}
Output:

[Hello World Hi]
[Hello World Hi]

func Uniq

func Uniq[S ~[]E, E comparable](original S) S

Creates a new slice based on the original slice and removes all the duplicated items.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{1, 2, 3, 3, 4, 3, 2, 5, 5, 1}
	list2 := slicex.Uniq(list1)

	fmt.Println(list2)
}
Output:

[1 2 3 4 5]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World", "Hello", "A-yon"}
	list2 := slicex.Uniq(list1)

	fmt.Println(list2)
}
Output:

[Hello World A-yon]

func UniqBy

func UniqBy[S ~[]M, M ~map[K]V, K comparable, V comparable](original S, key K) S

Creates a new slice based on the original slice and remove all the duplicated items identified by the given key.

Example
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []map[string]string{
		{
			"id":  "world",
			"tag": "A",
		},
		{
			"id":  "ayon",
			"tag": "B",
		},
		{
			"id":  "world",
			"tag": "C",
		},
		{
			"name": "foo", // this item will be removed from the result since we order the slice
			"tag":  "D",   // by `id` which is missing here.
		},
		nil, // nil will be ignored and removed
	}
	list2 := slicex.UniqBy(list1, "id")

	fmt.Println(list2)
}
Output:

[map[id:world tag:A] map[id:ayon tag:B]]

func Unshift

func Unshift[S ~[]T, T any](s *S, items ...T) int

Adds the specified items to the head of the slice and returns the new length of the slice.

This function mutates the input slice.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []int{0, 1, 2}
	length := slicex.Unshift(&list, -2, -1)

	fmt.Println(list)
	fmt.Println(length)
}
Output:

[-2 -1 0 1 2]
5
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list := []string{"Hello", "World"}
	length := slicex.Unshift(&list, "Hi", "A-yon")

	fmt.Println(list)
	fmt.Println(length)
}
Output:

[Hi A-yon Hello World]
4

func Xor

func Xor[S ~[]T, T comparable](sources ...S) S

Creates a slice of unique values that is the symmetric difference of the given sources.

Example (Int)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []int{0, 1, 2, 3, 4, 5}
	list2 := []int{2, 3, 4, 5, 6, 7}
	list3 := slicex.Xor(list1, list2)
	list4 := slicex.Xor(list1, list2, nil) // nil will be ignored

	fmt.Println(list3)
	fmt.Println(list4)
}
Output:

[0 1 6 7]
[0 1 6 7]
Example (String)
package main

import (
	"fmt"

	"github.com/ayonli/goext/slicex"
)

func main() {
	list1 := []string{"Hello", "World"}
	list2 := []string{"Hi", "World"}
	list3 := slicex.Xor(list1, list2)
	list4 := slicex.Xor(list1, list2, nil) // nil will be ignored

	fmt.Println(list3)
	fmt.Println(list4)
}
Output:

[Hello Hi]
[Hello Hi]

Types

This section is empty.

Jump to

Keyboard shortcuts

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