Gofunc is a free library that allows you to write clean, elegant code for working with arrays of data. With Gofunc, you can process a slice in a functional style, which is very convenient and more readable. Gofunc will save you time, which you can use for more serious stuff in your code.
Below you can see user slicing processing without Gofunc and with Gofunc. Algorithm of operations for working with users:
- for each user, increase the age by 1;
- leave only those users who are 18 or older;
- sort users by age;
- reverse users;
- print information to the console about each user;
type User struct {
Id int64
Name string
Age int
}
var Users = []User{
{1, "Kate", 25}, {2, "John", 17},
{3, "Sam", 22}, {4, "Marina", 15},
{5, "Nikita", 32}, {6, "Ksenia", 16},
{7, "Alex", 11}, {8, "Tony", 50},
{9, "Max", 32}, {10, "Veronika", 4},
}
func WithoutGofunc() {
copyUsers := make([]User, len(Users))
filteredUsers := make([]User, 0, len(Users))
copy(copyUsers, Users)
for i := 0; i < len(copyUsers); i++ {
copyUsers[i].Age++
}
for i := 0; i < len(copyUsers); i++ {
if copyUsers[i].Age >= 18 {
filteredUsers = append(filteredUsers, copyUsers[i])
}
}
QuickSortByUserAge(filteredUsers)
for i := 0; i < len(filteredUsers)/2; i++ {
filteredUsers[i], filteredUsers[len(filteredUsers)-i-1] =
filteredUsers[len(filteredUsers)-i-1], filteredUsers[i]
}
for i := 0; i < len(filteredUsers); i++ {
fmt.Printf("%+v\n", filteredUsers[i])
}
}
func WithGofunc() {
collection := gofunc.New(Users)
collection.
Map(func(el User) User { el.Age++; return el }).
Filter(func(el User) bool { return el.Age >= 18 }).
Sort(func(arr []User) { QuickSortByUserAge(arr) }).
Reverse().
ForEach(func(el User) { fmt.Printf("%+v\n", el) })
}
As you can see, the code looks shorter and prettier in the second variant.
You can play with the code in goplay space: gofunc example.
New[T comparable](arr []T) *collection[T]
Returns a collection (collection is a wrapper over a slice).
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
}
Generate[T comparable](script func() T, limit int) *collection[T]
Generates a collection based on the received function. The number of elements is given by the second input argument.
{
i := 0
collection := gofunc.Generate(func() int { i++; return i }, 10)
collection.ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
}
- ForEach
- Map
- FlatMap
- Reduce
- Filter
- Match
- AllMatch
- Distinct
- Limit
- Skip
- Sort
- Reverse
- Replace
- ReplaceAll
- Max
- Min
- Len
- ToSlice
- ToString
ForEach(f func(el T))
Performs an action for each element of this collection.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
collection.
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 2, 3, 4, 5,
}
Map(f func(el T) T) *collection[T]
Returns a collection consisting of the results of applying the given function to the elements of this collection.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
collection.
Map(func(el int) int { return el * el }).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 4, 9, 16, 25,
}
FlatMap(predicate func(el T) (T, T)) *collection[T]
Returns a collection consisting of the results of replacing each element of this collection with the contents of a mapped collection produced by applying the provided mapping function to each element.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
collection.
FlatMap(func(el int) (int, int) { return el, el + 1 }).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
}
Reduce(f func(el, accum T) T) T
Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
sum := collection.
Reduce(func(el, accum int) int { return el + accum })
fmt.Println(sum) // 15
}
Filter(f func(el T) bool) *collection[T]
Returns a collection consisting of the elements of this collection that match the given condition.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
collection.
Filter(func(el int) bool { return el%2 != 0 }).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 3, 5,
}
Match(f func(el T) bool) bool
Returns whether any elements of this collection match the provided condition.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
isMatched := collection.
Match(func(el int) bool { return el < 0 })
fmt.Println(isMatched) // false
}
AllMatch(f func(el T) bool) bool
Returns whether all elements of this collection match the provided condition.
{
slice := []int{1, 2, 3, 4, 5}
collection := gofunc.New(slice)
isAllMatched := collection.
AllMatch(func(el int) bool { return el > 0 })
fmt.Println(isAllMatched) // true
}
Distinct() *collection[T]
Returns a collection consisting of the distinct elements.
{
slice := []int{1, 2, 1, 4, 2, -2, 10, 1}
collection := gofunc.New(slice)
collection.
Distinct().
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 2, 4, -2, 10,
}
Limit(n int) *collection[T]
Returns a collection consisting of the elements of this collection, truncated to be no longer than n in length.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
collection := gofunc.New(slice)
collection.
Limit(6).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 1, 2, 3, 4, 5, 6,
}
Skip(n int) *collection[T]
Returns a collection consisting of the remaining elements of this collection after discarding the first n elements of the collection.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
collection := gofunc.New(slice)
collection.
Skip(6).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 7, 8, 9,
}
Sort(f func(arr []T)) *collection[T]
Returns a collection consisting of the elements of this collection, sorted according by input function.
{
slice := []int{0, -5, -7, 1, 3, 2, 11, 8, 4}
collection := gofunc.New(slice)
collection.
Sort(func(arr []int) { sort.Ints(arr) }).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // -7, -5, 0, 1, 2, 3, 4, 8, 11,
}
Reverse() *collection[T]
Returns a collection consisting of the elements of this collection, in reverse order.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
collection := gofunc.New(slice)
collection.
Reverse().
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 9, 8, 7, 6, 5, 4, 3, 2, 1,
}
Replace(targets []T, replacement T) *collection[T]
Replaces all the first matching elements of the collection passed to targets with the element passed to replacement.
{
slice := []int{1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6}
collection := gofunc.New(slice)
collection.
Replace([]int{1, 3, 5}, 10).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 10, 2, 10, 4, 10, 1, 2, 3, 4, 5, 6,
}
ReplaceAll(targets []T, replacement T) *collection[T]
Replaces all elements of the collection passed to the target objects with the element passed to replace.
{
slice := []int{1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 6}
collection := gofunc.New(slice)
collection.
Replace([]int{1, 3, 5}, 10).
ForEach(func(el int) { fmt.Printf("%d, ", el) }) // 10, 2, 10, 4, 10, 10, 2, 10, 4, 10, 6,
}
Max(compareFunc func(firstEl, secondEl T) T) T
Returns the maximum element of this collection according to the provided compare function.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
collection := gofunc.New(slice)
max := collection.
Max(func(firstEl, secondEl int) int {
return int(math.Max(float64(firstEl), float64(secondEl)))
})
fmt.Println(max) // 9
}
Min(compareFunc func(firstEl, secondEl T) T) T
Returns the minimum element of this collection according to the provided compare function.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
collection := gofunc.New(slice)
min := collection.
Min(func(firstEl, secondEl int) int {
return int(math.Min(float64(firstEl), float64(secondEl)))
})
fmt.Println(min) // 1
}
Len() int
Returns the count of elements in collection.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
collection := gofunc.New(slice)
fmt.Println(collection.Len()) // 10
}
ToSlice() []T
Converts a collection to a slice of elements.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
collection := gofunc.New(slice)
newSlice := collection.
Map(func(el int) int { return el * 3 }).
Filter(func(el int) bool { return el%2 == 0 }).
ToSlice()
fmt.Printf("%T: %v", newSlice, newSlice) // []int: [6 12 18 24 30]
}
ToString(f func(el T) string) string
Converts a collection to a string.
{
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
collection := gofunc.New(slice)
newSlice := collection.
Map(func(el int) int { return el * 3 }).
Filter(func(el int) bool { return el%2 == 0 }).
ToString(func(el int) string { return strconv.Itoa(el) + " " })
fmt.Printf("%T: %v", newSlice, newSlice) // string: 6 12 18 24 30
}
New[T, V comparable](slice []T, convertFunc func(el T) V) []V
Converts a slice of type T to a slice of type V.
{
slice := []int{1, 2, 3, 4, 5}
strSlice := convert.New(slice, convert.IntToString[int])
fmt.Printf("%T %v\n", strSlice, strSlice) // []string [1 2 3 4 5]
}
There is a set of ready-made functions for converting:
IntToString[T ints | uints](el T) string
FloatToString[T floats](el T) string
BoolToString(el bool) string
RuneToString(el rune) string
ComplexToString[T complex](el T) string