fun

package module
v0.0.0-...-62ed2a5 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2024 License: Apache-2.0 Imports: 1 Imported by: 1

README

fun

GoDoc

Simple generic utility functions to reduce golang boilerplate
  • Inspired by Kotlin and Rust collection functions
  • Supplement to the generic functions in golang.org/x/exp/slices and golang.org/x/exp/maps
  • Note: The Go compiler does not currently inline generic callback functions. So please use your judgement while using functions from this library that involve callbacks. Use them when the expressiveness is worth any performance degration compared to handcoded for loop boilerplate.

List of functions

All
  • Returns true if all elements return true for given predicate
All([]int{1, 2, 3, 4, 5}, func(i int)bool {return i < 7})
// true

All([]int{1, 2, 3, 4, 5}, func(i int)bool {return i % 2 == 0})
// false

Any
  • Returns true if at least one element returns true for given predicate
Any([]int{1, 2, 3}, func(i int)bool {return i%2==0})
// true

Any([]int{1, 2, 3}, func(i int)bool {return i > 7})
// false
AppendToGroup
  • Adds the key, value to the given map where each key maps to a slice of values
group := make(map[string][]int)

AppendToGroup(grp, "a", 1)
AppendToGroup(grp, "b", 2)
AppendToGroup(grp, "a", 10)
AppendToGroup(grp, "b", 20)
AppendToGroup(grp, "a", 100)
AppendToGroup(grp, "b", 200)

// {"a":[1, 10, 100], "b":[2, 20, 200]}
Associate
  • Returns a map containing key-value pairs returned by the given function applied to the elements of the given slice
Associate([]int{1, 2, 3, 4}, func(i int) (string, int) {
    return fmt.Sprintf("M%d", i), i * 10
})
// {"M1": 10, "M2": 20, "M3": 30, "M4": 40}
Chunked
  • Splits the slice into a slice of slices, each not exceeding given chunk size
  • The last slice might have fewer elements than the given chunk size
Chunked([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}, 2)
// [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
ChunkedBy
  • Splits the slice into a slice of slices, starting a new sub slice whenever the callback function returns false.
  • The callback function is passed the previous and current element.
input := []int{10, 20, 30, 40, 31, 31, 33, 34, 21, 22, 23, 24, 11, 12, 13, 14}
ChunkedBy(input, func(prev, next int) bool { return prev < next})
// [[10, 20, 30, 40], [31], [31, 33, 34], [21, 22, 23, 24], [11, 12, 13, 14]]
Distinct
  • Returns a slice containing only distinct elements from the given slice
Distinct([]int{1, 1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5})
// [1, 2, 3, 4, 5]
DistinctBy
  • Returns a slice containing only distinct elements from the given slice as distinguished by the given selector function
DistinctBy([]string{"a", "A", "b", "B", "c", "C"},func(s string) string {
	return strings.ToLower(s)
})
// ["a", "b", "c"]
Drop
  • Returns a slice containing all elements except the first n.
// letters = ['a'..'z']
Drop(letters, 23)
// ['x', 'y', 'z']
DropLast
  • Returns a slice containing all elements except the last n.
// letters = ['a'..'z']
DropLast(letters, 23)
// ['a', 'b', 'c']
DropWhile
  • Returns a slice containing all elements except the first elements that satisfy the given predicate.
// letters = ['a'..'z']
DropWhile(letters, func(r rune) bool { return r < 'x' })
// ['x', 'y', 'z']
DropLastWhile
  • Returns a slice containing all elements except the last elements that satisfy the given predicate.
// letters = ['a'..'z']
DropLastWhile(letters, func(r rune) bool { return r > 'c' })
// ['a', 'b', 'c']
Filter
  • Returns the slice obtained after retaining only those elements in the given slice for which the given function returns true
Filter([]int{1, 2, 3, 4, 5, 6, 7, 8}, func(i int)bool {return i%2==0})
// [2, 4, 6, 8]
FilterIndexed
  • Returns the slice obtained after retaining only those elements in the given slice for which the given function returns true
  • Predicate function receives the value as well as its index in the slice.
FilterIndexed([]int{0, 1, 2, 3, 4, 8, 6}, func(index int, v int) bool {
	return index == v
})
// [0, 1, 2, 3, 4, 6]
FilterMap
  • FilterMap returns the slice obtained after both filtering and mapping using the given function.
  • The function should return two values - the result of the mapping operation and whether the element should be included or dropped.
  • This is faster than doing separate filter and map operations, since it avoids extra allocations and slice traversals.
  • Inspired by std::iter::filter_map in Rust
FilterMap([]int{1, 2, 3, 4, 5},
    func(i int) (int, bool) {
        if i%2 != 0 {
            return i, false // drop odd numbers
        }
        return i * i, true // square even numbers
    })
// [4, 16]
FlatMap
  • Applies the given function to each element in the input slice and combines all resulting slices into one.
FlatMap([]int{1, 2, 3, 4, 5}, func(i int) []int { return []int{i, i * i} })
// [1, 1, 2, 4, 3, 9, 4, 16, 5, 25]
FlatMapIndexed
  • Applies the given function to each element in the input slice, which also receives the element's index, and combines all resulting slices into one.
FlatMap([]int{1, 2, 3, 4, 5}, func(idx, val int) []int { return []int{idx, val * val} })
// 0, 1, 1, 4, 2, 9, 3, 16, 4, 25
Fold
  • Accumulates values starting with given initial value and applying given function to current accumulator and each element of the given slice.
Fold([]int{1, 2, 3, 4, 5}, func(acc, v int) int { return acc + v })
// 15
FoldIndexed
  • Accumulates values starting with given initial value and applying given function to current accumulator and each element of the given slice.
  • Function also receives index of current element.
FoldIndexed([]int{1, 2, 3, 4, 5}, func(index, acc, v int) int {
	return acc + index*v
})
// 40
FoldItems
  • Accumulates values starting with given intial value and applying given function to current accumulator and each key, value of the given map.
  • Accumulator can be of any reference type.
m := map[int]int{1: 10, 2: 20, 3: 30}
FoldItems(m, func(acc map[string]string, k, v int) map[string]string {
    acc[fmt.Sprintf("entry_%d", k)] = fmt.Sprintf("%d->%d", k, v)
    return acc
})
// {"entry_1": "1->10", "entry_2": "2->20", "entry_3": "3->30"}
GetOrInsert
  • checks if a value corresponding to the given key is present in the map.
  • If present it returns the existing value.
  • If not present, it invokes the given callback function to get a new value for the given key, inserts it in the map and returns the new value
m := map[int]int{1:10, 2:20}
GetOrInsert(m, 3, func(i int) int {return i * 10})
// returns 30; m is updated to {1:10, 2:20, 3:30},
GroupBy
  • Returns a map where each key maps to slices of elements all having the same key as returned by the given function
GroupBy([]string{"a", "abc", "ab", "def", "abcd"}, func(s string) (int,string) {
	return len(s), s
})
// {1: ["a"], 2: ["ab"], 3: ["abc", "def"], 4: ["abcd"]},
Items
  • Returns the (key, value) pairs of the given map as a slice
// m := map[string][]int{"a": {1, 2, 3, 4}, "b": {1, 2}, "c": {1, 2, 3}}
Items(m)
// []*Pair[string, []int]{
//      {"a", []int{1, 2, 3, 4}},
//      {"b", []int{1, 2}},
//      {"c", []int{1, 2, 3}},
// }
Map
  • Returns the slice obtained after applying the given function over every element in the given slice
Map([]int{1, 2, 3, 4, 5}, func(i int) int { return i * i })
// [1, 4, 9, 16, 25]
MapIndexed
  • Returns the slice obtained after applying the given function over every element in the given slice
  • The function also receives the index of each element in the slice.
MapIndexed([]int{1, 2, 3, 4, 5}, func(index, i int) int { return index * i })
// [0, 2, 6, 12, 20]
Partition
  • Returns two slices where the first slice contains elements for which the predicate returned true and the second slice contains elements for which it returned false.
type person struct {
    name string
    age  int
}

tom := &person{"Tom", 18}
andy := &person{"Andy", 32}
sarah := &person{"Sarah", 22}

Partition([]*person{tom, andy, sarah}, func(p *person) bool { return p.age < 30 })
// [tom, sarah], [andy]
Reduce
  • Accumulates the values starting with the first element and applying the operation from left to right to the current accumulator value and each element.
  • The input slice must have at least one element.
Reduce([]int{1, 2, 3, 4, 5}, func(acc, v int) int { return acc + v })
// 15
ReduceIndexed
  • Accumulates the values starting with the first element and applying the operation from left to right to the current accumulator value and each element.
  • The input slice must have at least one element.
  • The function also receives the index of each element.
ReduceIndexed([]string{"a", "b", "c", "d"}, func(index int, acc, v string) string {
    return fmt.Sprintf("%s%s%d", acc, v, index)
})
// "ab1c2d3"
Reverse
  • Reverses the elements of the list in place.
// s = [1, 2, 3, 4, 5, 6, 7]
Reverse(s)
// s = [7, 6, 5, 4, 3, 2, 1]
Reversed
  • Returns a new list with the elements in reverse order.
// s = [1, 2, 3, 4, 5, 6, 7]
r := Reversed(s)
// r = [7, 6, 5, 4, 3, 2, 1]
// s = [1, 2, 3, 4, 5, 6, 7]
Take
  • Returns the slice obtained after taking the first n elements from the given slice.
// letters = ['a'..'z']
Take(letters, 2)
// ['a', 'b']
TakeLast
  • Returns the slice obtained after taking the last n elements from the given slice.
// letters = ['a'..'z']
TakeLast(letters, 2)
// ['y', 'z']
TakeWhile
  • Returns a slice containing the first elements satisfying the given predicate
// letters = ['a'..'z']
TakeWhile(letters,  func(s rune) bool { return s < 'f' })
// ['a', 'b', 'c', 'd', 'e']
TakeLastWhile
  • Returns a slice containing the last elements satisfying the given predicate
// letters = ['a'..'z']
TakeLastWhile(letters, func(s rune) bool { return s > 'w' })
// ['x', 'y', 'z']
TransformMap
  • Applies the given function to each key, value in the map, and returns a new map of the same type after transforming the keys and values depending on the callback functions return values.
  • If the last bool return value from the callback function is false, the entry is dropped
// filtering a map
// m = {"a":[1, 2, 3, 4] "b":[1, 2] "c":[1, 2, 3]}
TransformMap(m, 
    func(k string, v []int) (string, []int, bool) {
        if len(v) < 3 {
            return k, v, false
        }
        return k, v, true
    })
// drops all values with length less than 3
// {"a":[1, 2, 3, 4]  "c":[1, 2, 3]}


// transforming keys and values
// m = {"a":[1, 2, 3, 4] "b":[5, 6]}
TransformMap(m, 
    func(k string, v []int) (string, []int, bool) {
        newK := strings.ToUpper(k)
        newV := Map(v, func(i int) int { return i * 10 })
        return newK, newV, true
    })
// {"A":[10, 20, 30, 40]  "B":[50, 60]}
Unzip
  • Returns two slices, where:
  • the first slice is built from the first values of each pair from the input slice
  • the second slice is built from the second values of each pair
Unzip([]*Pair[string, int]{{"a", 1}, {"b", 2}, {"c", 3}})
// ["a", "b", "c"], [1, 2, 3]
Windowed
  • Returns a slice of sliding windows, each of the given size, and with the given step
  • Several last slices may have fewer elements than the given size
Windowed([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 5, 1)
// [
//     [1, 2, 3, 4, 5],
//     [2, 3, 4, 5, 6],
//     [3, 4, 5, 6, 7],
//     [4, 5, 6, 7, 8],
//     [5, 6, 7, 8, 9],
//     [6, 7, 8, 9, 10],
//     [7, 8, 9, 10],
//     [8, 9, 10],
//     [9, 10],
//     [10]
// ]

Windowed([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 5, 3)
// [
//     [1, 2, 3, 4, 5],
//     [4, 5, 6, 7, 8],
//     [7, 8, 9, 10],
//     [10]
// ]
Zip
  • Returns a slice of pairs from the elements of both slices with the same index
  • The returned slice has the length of the shortest input slice
Zip([]string{"a", "b", "c", "d"}, []int{1, 2, 3})
// []*Pair[string, int]{{"a", 1}, {"b", 2}, {"c", 3}}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All[T any](s []T, fn func(T) bool) bool

All returns true if all elements return true for given predicate

func Any

func Any[T any](s []T, fn func(T) bool) bool

Any returns true if at least one element returns true for given predicate

func AppendToGroup

func AppendToGroup[M ~map[K][]V, K comparable, V any](m M, k K, v V)

AppendToGroup adds the key, value to the given map where each key points to a slice of values

func Associate

func Associate[T, V any, K comparable](s []T, fn func(T) (K, V)) map[K]V

Associate returns a map containing key-value pairs returned by the given function applied to the elements of the given slice

func Chunked

func Chunked[T any](s []T, chunkSize int) [][]T

Chunked splits the slice into a slice of slices, each not exceeding given size The last slice might have fewer elements than the given size

func ChunkedBy

func ChunkedBy[T any](s []T, fn func(T, T) bool) [][]T

func Distinct

func Distinct[T comparable](s []T) []T

Distinct returns a slice containing only distinct elements from the given slice Elements will retain their original order.

func DistinctBy

func DistinctBy[T any, K comparable](s []T, fn func(T) K) []T

DistinctBy returns a slice containing only distinct elements from the given slice as distinguished by the given selector function Elements will retain their original order.

func Drop

func Drop[T any](s []T, n int) []T

Drop returns a slice containing all elements except the first n

func DropLast

func DropLast[T any](s []T, n int) []T

DropLast returns a slice containing all elements except the last n

func DropLastWhile

func DropLastWhile[T any](s []T, fn func(T) bool) []T

DropLastWhile returns a slice containing all elements except the last elements that satisfy the given predicate

func DropWhile

func DropWhile[T any](s []T, fn func(T) bool) []T

DropWhile returns a slice containing all elements except the first elements that satisfy the given predicate

func Filter

func Filter[T any](s []T, fn func(T) bool) []T

Filter returns the slice obtained after retaining only those elements in the given slice for which the given function returns true

func FilterIndexed

func FilterIndexed[T any](s []T, fn func(int, T) bool) []T

FilterIndexed returns the slice obtained after retaining only those elements in the given slice for which the given function returns true. Predicate receives the value as well as its index in the slice.

func FilterMap

func FilterMap[T1, T2 any](
	s []T1,
	fn func(T1) (T2, bool),
) []T2

FilterMap returns the slice obtained after both filtering and mapping using the given function. The function should return two values - first, the result of the mapping operation and second, whether the element should be included or not. This is faster than doing a separate filter and map operations, since it avoids extra allocations and slice traversals.

func FlatMap

func FlatMap[T1, T2 any](s []T1, fn func(T1) []T2) []T2

FlatMap transforms a slice of T1 elementss (s) into a slice of T2 elements. The transformation is defined by the function fn, which takes a T1 element and returns a slice of T2 elements. This function applies fn to every element in s, and combines the results into a single, "flattened" slice of T2 elements.

func FlatMapIndexed

func FlatMapIndexed[T1, T2 any](s []T1, fn func(int, T1) []T2) []T2

FlatMapIndexed transforms a slice of T1 elements (s) into a slice of T2 elements. The transformation is defined by the function fn, which takes a T1 element and the index to the element, and returns a slice of T2 elements. This function applies fn to every element in s, and combines the results into a single, "flattened" slice of T2 elements.

func Fold

func Fold[T, R any](s []T, initial R, fn func(R, T) R) R

Fold accumulates values starting with given initial value and applying given function to current accumulator and each element.

func FoldIndexed

func FoldIndexed[T, R any](s []T, initial R, fn func(int, R, T) R) R

FoldIndexed accumulates values starting with given initial value and applying given function to current accumulator and each element. Function also receives index of current element.

func FoldItems

func FoldItems[M ~map[K]V, K comparable, V, R any](
	m M,
	initial R,
	fn func(R, K, V) R,
) R

FoldItems accumulates values starting with given intial value and applying given function to current accumulator and each key, value.

func GetOrInsert

func GetOrInsert[M ~map[K]V, K comparable, V any](m M, k K, fn func(K) V) V

GetOrInsert checks if a value corresponding to the given key is present in the map. If present it returns the existing value. If not, it invokes the given callback function to get a new value for the given key, inserts it in the map and returns the new value

func GroupBy

func GroupBy[T, V any, K comparable](
	s []T,
	fn func(T) (K, V),
) map[K][]V

GroupBy returns a map containing key to list of values returned by the given function applied to the elements of the given slice

func Map

func Map[T1, T2 any](s []T1, fn func(T1) T2) []T2

Map returns the slice obtained after applying the given function over every element in the given slice

func MapIndexed

func MapIndexed[T1, T2 any](s []T1, fn func(int, T1) T2) []T2

MapIndexed returns the slice obtained after applying the given function over every element in the given slice. The function also receives the index of each element in the slice.

func Partition

func Partition[T any](s []T, fn func(T) bool) ([]T, []T)

Partition returns two slices where the first slice contains elements for which the predicate returned true and the second slice contains elements for which it returned false.

func Reduce

func Reduce[T any](s []T, fn func(T, T) T) T

Reduce accumulates the values starting with the first element and applying the operation from left to right to the current accumulator value and each element The input slice must have at least one element.

func ReduceIndexed

func ReduceIndexed[T any](s []T, fn func(int, T, T) T) T

ReduceIndexed accumulates the values starting with the first element and applying the operation from left to right to the current accumulator value and each element The input slice must have at least one element. The function also receives the index of the element.

func Reverse

func Reverse[T any](s []T)

Reverse reverses the elements of the list in place

func Reversed

func Reversed[T any](s []T) []T

Reversed returns a new list with the elements in reverse order

func Take

func Take[T any](s []T, n int) []T

Take returns the slice obtained after taking the first n elements from the given slice. If n is greater than the length of the slice, returns the entire slice

func TakeLast

func TakeLast[T any](s []T, n int) []T

TakeLast returns the slice obtained after taking the last n elements from the given slice.

func TakeLastWhile

func TakeLastWhile[T any](s []T, fn func(T) bool) []T

TakeLastWhile returns a slice containing the last elements satisfying the given predicate

func TakeWhile

func TakeWhile[T any](s []T, fn func(T) bool) []T

TakeWhile returns a list containing the first elements satisfying the given predicate

func TransformMap

func TransformMap[M ~map[K]V, K comparable, V any](
	m M,
	fn func(k K, v V) (K, V, bool),
) M

TransformMap applies the given function to each key, value in the map, and returns a new map of the same type after transforming the keys and values depending on the callback functions return values. If the last bool return value from the callback function is false, the entry is dropped

func Unzip

func Unzip[T1 any, T2 any](ps []*Pair[T1, T2]) ([]T1, []T2)

Unzip returns two slices, where the first slice is built from the first values of each pair from the input slice, and the second slice is built from the second values of each pair

func Windowed

func Windowed[T any](s []T, size, step int) [][]T

Windowed returns a slice of sliding windows into the given slice of the given size, and with the given step

Types

type Pair

type Pair[T1, T2 any] struct {
	Fst T1
	Snd T2
}

Pair represents a generic pair of two values

func Items

func Items[M ~map[K]V, K comparable, V any](m M) []*Pair[K, V]

Items returns the (key, value) pairs of the given map as a slice

func Zip

func Zip[T1 any, T2 any](s1 []T1, s2 []T2) []*Pair[T1, T2]

Zip returns a slice of pairs from the elements of both slices with the same index. The returned slice has the length of the shortest input slice

func (Pair[T1, T2]) String

func (p Pair[T1, T2]) String() string

Jump to

Keyboard shortcuts

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