This documentation is still new and evolving. If you spot any mistakes, unclear explanations, or missing details, please open an issue.
Your feedback helps us improve!
Core - Slice helpersโ
This page lists all operations on slices, available in the core package of lo.
Countโ
Counts the number of elements in the collection that equal a given value.
lo.Count([]int{1, 5, 1}, 1)
// 2Similar:Prototype:func Count[T comparable](collection []T, value T) intCountByโ
Counts the number of elements for which the predicate is true.
lo.CountBy([]int{1, 5, 1}, func(i int) bool {
return i < 4
})
// 2Prototype:func CountBy[T any](collection []T, predicate func(item T) bool) intCountValuesโ
Counts the number of occurrences of each element in the collection.
lo.CountValues([]int{1, 2, 2})
// map[int]int{1: 1, 2: 2}Prototype:func CountValues[T comparable](collection []T) map[T]intCountValuesByโ
Counts the number of each transformed value (equivalent to Map followed by CountValues).
isEven := func(v int) bool {
return v%2 == 0
}
lo.CountValuesBy([]int{1, 2, 2}, isEven)
// map[bool]int{false: 1, true: 2}Similar:Prototype:func CountValuesBy[T any, U comparable](collection []T, transform func(item T) U) map[U]intSlices the collection around the first instance of the separator, returning before, after, and whether it was found.
left, right, found := lo.Cut([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"b", "c", "d"})
// left: []string{"a"}
// right: []string{"e", "f", "g"}
// found: true
left, right, found = lo.Cut([]string{"a", "b", "c"}, []string{"z"})
// left: []string{"a", "b", "c"}
// right: []string{}
// found: falsePrototype:func Cut[T comparable, Slice ~[]T](collection Slice, separator Slice) (before Slice, after Slice, found bool)CutPrefixโ
Returns the collection without the provided leading prefix and a boolean indicating whether it was present.
right, found := lo.CutPrefix([]string{"a", "b", "c", "d"}, []string{"a", "b", "c"})
// right: []string{"d"}
// found: true
right, found = lo.CutPrefix([]string{"a", "b", "c"}, []string{"b"})
// right: []string{"a", "b", "c"}
// found: falsePrototype:func CutPrefix[T comparable, Slice ~[]T](collection Slice, separator Slice) (after Slice, found bool)CutSuffixโ
Returns the collection without the provided trailing suffix and a boolean indicating whether it was present.
left, found := lo.CutSuffix([]string{"a", "b", "c", "d", "e", "f", "g"}, []string{"f", "g"})
// left: []string{"a", "b", "c", "d", "e"}
// found: true
left, found = lo.CutSuffix([]string{"a", "b", "c"}, []string{"b"})
// left: []string{"a", "b", "c"}
// found: falsePrototype:func CutSuffix[T comparable, Slice ~[]T](collection Slice, separator Slice) (before Slice, found bool)Filterโ
Iterates over a collection and returns a slice of all the elements the predicate function returns
truefor.even := lo.Filter([]int{1, 2, 3, 4}, func(x int, index int) bool {
return x%2 == 0
})
// []int{2, 4}Prototype:func Filter[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) SliceIsSortedโ
Checks if a slice is sorted in ascending order.
lo.IsSorted([]int{0, 1, 2, 3, 4, 5})
// trueSimilar:Prototype:func IsSorted[T constraints.Ordered](collection []T) boolIsSortedByโ
Checks if a slice is sorted based on a key computed for each element.
ok := lo.IsSortedBy([]string{"a", "bb", "ccc"}, func(s string) int {
return len(s)
})
// truePrototype:func IsSortedBy[T any, K constraints.Ordered](collection []T, iteratee func(item T) K) boolReplaceโ
Returns a copy of the slice with the first n non-overlapping instances of old replaced by new.
in := []int{0, 1, 0, 1, 2, 3, 0}
lo.Replace(in, 0, 42, 2)
// []int{42, 1, 42, 1, 2, 3, 0}Similar:Prototype:func Replace[T comparable, Slice ~[]T](collection Slice, old T, nEw T, n int) SliceReplaceAllโ
Returns a copy of the slice with all non-overlapping instances of old replaced by new.
in := []int{0, 1, 0, 1, 2, 3, 0}
lo.ReplaceAll(in, 0, 42)
// []int{42, 1, 42, 1, 2, 3, 42}Prototype:func ReplaceAll[T comparable, Slice ~[]T](collection Slice, old T, nEw T) SliceSliceโ
Returns a copy of a slice from
startup to, but not including,end. Likeslice[start:end], but does not panic on overflow.in := []int{0, 1, 2, 3, 4}
lo.Slice(in, 2, 6)
// []int{2, 3, 4}Prototype:func Slice[T any, Slice ~[]T](collection Slice, start int, end int) SliceSpliceโ
Inserts multiple elements at the specified index, with support for negative indices and automatic bounds handling. Negative indices count from the end (-1 means before last element), and indices beyond the slice length append to the end.
// Basic insertion at position 1
result := lo.Splice([]string{"a", "b"}, 1, "1", "2")
// result: []string{"a", "1", "2", "b"}
// Negative index: -1 means before the last element
result = lo.Splice([]string{"a", "b"}, -1, "1", "2")
// result: []string{"a", "1", "2", "b"}
// Index overflow: when index > len(slice), elements are appended
result = lo.Splice([]string{"a", "b"}, 42, "1", "2")
// result: []string{"a", "b", "1", "2"}
// Insert at beginning (index 0)
result = lo.Splice([]int{3, 4, 5}, 0, 1, 2)
// result: []int{1, 2, 3, 4, 5}
// Insert before last element with negative index
result = lo.Splice([]int{1, 2, 3}, -2, 99)
// result: []int{1, 99, 2, 3}
// No elements to insert returns original slice
result = lo.Splice([]string{"a", "b"}, 1)
// result: []string{"a", "b"}Prototype:func Splice[T any, Slice ~[]T](collection Slice, i int, elements ...T) SliceSubsetโ
Returns a copy of a slice from
offsetup tolengthelements. Likeslice[start:start+length], but does not panic on overflow.in := []int{0, 1, 2, 3, 4}
lo.Subset(in, 2, 3)
// []int{2, 3, 4}Prototype:func Subset[T any, Slice ~[]T](collection Slice, offset int, length uint) SliceTrimโ
Removes all leading and trailing elements in the cutset from the collection.
result := lo.Trim([]int{0, 1, 2, 0, 3, 0}, []int{1, 0})
// []int{2, 0, 3}
result = lo.Trim([]string{"hello", "world", " "}, []string{" ", ""})
// []string{"hello", "world"}Prototype:func Trim[T comparable, Slice ~[]T](collection Slice, cutset Slice) SliceTrimLeftโ
Removes all leading elements found in the cutset from the collection.
result := lo.TrimLeft([]int{0, 1, 2, 0, 3, 0}, []int{1, 0})
// []int{2, 0, 3, 0}
result = lo.TrimLeft([]string{"hello", "world", " "}, []string{" ", ""})
// []string{"hello", "world", " "}Prototype:func TrimLeft[T comparable, Slice ~[]T](collection Slice, cutset Slice) SliceTrimPrefixโ
Removes all leading occurrences of the given prefix from the collection.
result := lo.TrimPrefix([]int{1, 2, 1, 2, 3, 1, 2, 4}, []int{1, 2})
// []int{3, 1, 2, 4}
result = lo.TrimPrefix([]string{"hello", "world", "hello", "test"}, []string{"hello"})
// []string{"world", "hello", "test"}Similar:Prototype:func TrimPrefix[T comparable, Slice ~[]T](collection Slice, prefix Slice) SliceTrimRightโ
Removes all trailing elements found in the cutset from the collection.
result := lo.TrimRight([]int{0, 1, 2, 0, 3, 0}, []int{0, 3})
// []int{0, 1, 2}
result = lo.TrimRight([]string{"hello", "world", " "}, []string{" ", ""})
// []string{"hello", "world", ""}Similar:Prototype:func TrimRight[T comparable, Slice ~[]T](collection Slice, cutset Slice) SliceTrimSuffixโ
Removes all trailing occurrences of the given suffix from the collection.
result := lo.TrimSuffix([]int{1, 2, 3, 1, 2, 4, 2, 4, 2, 4}, []int{2, 4})
// []int{1, 2, 3, 1}
result = lo.TrimSuffix([]string{"hello", "world", "hello", "test"}, []string{"test"})
// []string{"hello", "world", "hello"}Similar:Prototype:func TrimSuffix[T comparable, Slice ~[]T](collection Slice, suffix Slice) SliceCountByErrโ
Counts the number of elements for which the predicate is true. Returns an error if the predicate function fails, stopping iteration immediately.
count, err := lo.CountByErr([]int{1, 5, 1}, func(i int) (bool, error) {
if i == 5 {
return false, fmt.Errorf("5 not allowed")
}
return i < 4, nil
})
// 0, error("5 not allowed")count, err := lo.CountByErr([]int{1, 5, 1}, func(i int) (bool, error) {
return i < 4, nil
})
// 2, nilSimilar:Prototype:func CountByErr[T any](collection []T, predicate func(item T) (bool, error)) (int, error)FilterErrโ
Iterates over a collection and returns a slice of all the elements the predicate function returns
truefor. If the predicate returns an error, iteration stops immediately and returns the error.even, err := lo.FilterErr([]int{1, 2, 3, 4}, func(x int, index int) (bool, error) {
if x == 3 {
return false, errors.New("number 3 is not allowed")
}
return x%2 == 0, nil
})
// []int(nil), error("number 3 is not allowed")even, err := lo.FilterErr([]int{1, 2, 3, 4}, func(x int, index int) (bool, error) {
return x%2 == 0, nil
})
// []int{2, 4}, nilPrototype:func FilterErr[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) (bool, error)) (Slice, error)Transforms each element in a slice to a new type using a function. Takes both the element and its index, making it useful for transformations that need positional context.
// Basic type transformation
transformed := lo.Map([]int64{1, 2, 3, 4}, func(x int64, index int) string {
return strconv.FormatInt(x, 10)
})
// transformed: []string{"1", "2", "3", "4"}// Transforming structs
type Person struct {
FirstName string
LastName string
Age int
}
people := []Person{
{FirstName: "John", LastName: "Doe", Age: 25},
{FirstName: "Jane", LastName: "Smith", Age: 30},
}
fullNames := lo.Map(people, func(p Person, index int) string {
return fmt.Sprintf("%s %s", p.FirstName, p.LastName)
})
// fullNames: []string{"John Doe", "Jane Smith"}Prototype:func Map[T any, R any](collection []T, transform func(item T, index int) R) []RMapErrโ
Transforms each element in a slice to a new type using a function that can return an error. Stops iteration immediately when an error is encountered.
// Error case - stops on first error
result, err := lo.MapErr([]int{1, 2, 3, 4}, func(x int, _ int) (string, error) {
if x == 3 {
return "", fmt.Errorf("number 3 is not allowed")
}
return strconv.Itoa(x), nil
})
// []string(nil), error("number 3 is not allowed")// Success case
result, err := lo.MapErr([]int{1, 2, 3, 4}, func(x int, _ int) (string, error) {
return strconv.Itoa(x), nil
})
// []string{"1", "2", "3", "4"}, nilPrototype:func MapErr[T any, R any](collection []T, transform func(item T, index int) (R, error)) ([]R, error)UniqMapโ
Manipulates a slice and transforms it to a slice of another type with unique values.
type User struct {
Name string
Age int
}
users := []User{{Name: "Alex", Age: 10}, {Name: "Alex", Age: 12}, {Name: "Bob", Age: 11}, {Name: "Alice", Age: 20}}
names := lo.UniqMap(users, func(u User, index int) string {
return u.Name
})
// []string{"Alex", "Bob", "Alice"}Prototype:func UniqMap[T any, R comparable](collection []T, transform func(item T, index int) R) []RFilterMapโ
Returns a slice obtained after both filtering and mapping using the given callback function.
The callback function should return two values: the result of the mapping operation and whether the result element should be included or not.
matching := lo.FilterMap([]string{"cpu", "gpu", "mouse", "keyboard"}, func(x string, _ int) (string, bool) {
if strings.HasSuffix(x, "pu") {
return "xpu", true
}
return "", false
})
// []string{"xpu", "xpu"}Prototype:func FilterMap[T any, R any](collection []T, callback func(item T, index int) (R, bool)) []RFlatMapโ
Manipulates a slice and transforms and flattens it to a slice of another type. The transform function can either return a slice or a
nil, and in thenilcase no value is added to the final slice.out := lo.FlatMap([]int64{0, 1, 2}, func(x int64, _ int) []string {
return []string{strconv.FormatInt(x, 10), strconv.FormatInt(x, 10)}
})
// []string{"0", "0", "1", "1", "2", "2"}Prototype:func FlatMap[T any, R any](collection []T, transform func(item T, index int) []R) []RFlatMapErrโ
Manipulates a slice and transforms and flattens it to a slice of another type using a function that can return an error. Stops iteration immediately when an error is encountered.
// Error case - stops on first error
result, err := lo.FlatMapErr([]int64{0, 1, 2, 3}, func(x int64, _ int) ([]string, error) {
if x == 2 {
return nil, fmt.Errorf("number 2 is not allowed")
}
return []string{strconv.FormatInt(x, 10), strconv.FormatInt(x, 10)}, nil
})
// []string(nil), error("number 2 is not allowed")// Success case
result, err := lo.FlatMapErr([]int64{0, 1, 2}, func(x int64, _ int) ([]string, error) {
return []string{strconv.FormatInt(x, 10), strconv.FormatInt(x, 10)}, nil
})
// []string{"0", "0", "1", "1", "2", "2"}, nilPrototype:func FlatMapErr[T any, R any](collection []T, transform func(item T, index int) ([]R, error)) ([]R, error)Reduceโ
Reduces a collection to a single value by accumulating results of an accumulator function. Each call receives the previous result value.
sum := lo.Reduce([]int{1, 2, 3, 4}, func(agg int, item int, _ int) int {
return agg + item
}, 0)
// 10Prototype:func Reduce[T any, R any](collection []T, accumulator func(agg R, item T, index int) R, initial R) RReduceErrโ
Reduces a collection to a single value by accumulating results of an accumulator function that can return an error. Stops iteration immediately when an error is encountered.
// Error case - stops on first error
result, err := lo.ReduceErr([]int{1, 2, 3, 4}, func(agg int, item int, _ int) (int, error) {
if item == 3 {
return 0, fmt.Errorf("number 3 is not allowed")
}
return agg + item, nil
}, 0)
// 0, error("number 3 is not allowed")// Success case
result, err := lo.ReduceErr([]int{1, 2, 3, 4}, func(agg int, item int, _ int) (int, error) {
return agg + item, nil
}, 0)
// 10, nilPrototype:func ReduceErr[T any, R any](collection []T, accumulator func(agg R, item T, index int) (R, error), initial R) (R, error)ReduceRightโ
Like Reduce except it iterates from right to left and accumulates into a single value.
result := lo.ReduceRight([][]int{{0, 1}, {2, 3}, {4, 5}}, func(agg []int, item []int, _ int) []int {
return append(agg, item...)
}, []int{})
// []int{4, 5, 2, 3, 0, 1}Prototype:func ReduceRight[T any, R any](collection []T, accumulator func(agg R, item T, index int) R, initial R) RReduceRightErrโ
Like Reduce but iterates from right to left and accumulates into a single value using an accumulator function that can return an error. Stops iteration immediately when an error is encountered.
// Error case - stops on first error (from right to left)
result, err := lo.ReduceRightErr([][]int{{0, 1}, {2, 3}, {4, 5}}, func(agg []int, item []int, _ int) ([]int, error) {
if len(item) > 0 && item[0] == 4 {
return nil, fmt.Errorf("element starting with 4 is not allowed")
}
return append(agg, item...), nil
}, []int{})
// []int(nil), error("element starting with 4 is not allowed")// Success case
result, err := lo.ReduceRightErr([]int{1, 2, 3, 4}, func(agg int, item int, _ int) (int, error) {
return agg + item, nil
}, 0)
// 10, nilSimilar:Prototype:func ReduceRightErr[T any, R any](collection []T, accumulator func(agg R, item T, index int) (R, error), initial R) (R, error)ForEachโ
Iterates over elements of a collection and invokes the callback for each element.
lo.ForEach([]string{"hello", "world"}, func(x string, _ int) {
println(x)
})
// prints "hello\nworld\n"Prototype:func ForEach[T any](collection []T, callback func(item T, index int))ForEachWhileโ
Iterates over elements of a collection and invokes the predicate for each element until false is returned.
numbers := []int64{1, 2, -9223372036854775808, 4}
lo.ForEachWhile(numbers, func(x int64, _ int) bool {
if x < 0 {
return false
}
fmt.Println(x)
return true
})
// Output:
// 1
// 2Prototype:func ForEachWhile[T any](collection []T, predicate func(item T, index int) bool)Timesโ
Invokes the predicate n times, returning a slice of results. The predicate receives the index on each call.
lo.Times(3, func(i int) string {
return strconv.Itoa(i)
})
// []string{"0", "1", "2"}Prototype:func Times[T any](count int, iteratee func(index int) T) []TUniqโ
Returns a duplicate-free version of a slice, keeping only the first occurrence of each value. Order is preserved.
lo.Uniq([]int{1, 2, 2, 1})
// []int{1, 2}Similar:Prototype:func Uniq[T comparable, Slice ~[]T](collection Slice) SliceUniqByโ
Returns a duplicate-free version of a slice based on a computed key. Keeps only the first element for each unique key.
lo.UniqBy(
[]int{0, 1, 2, 3, 4, 5},
func(i int) int {
return i % 3
},
)
// []int{0, 1, 2}Similar:Prototype:func UniqBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) SliceUniqByErrโ
Returns a duplicate-free version of a slice based on a computed key using an iteratee that can return an error. Stops iteration immediately when an error is encountered. Keeps only the first element for each unique key.
// Error case - stops on first error
result, err := lo.UniqByErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, error) {
if i == 3 {
return 0, fmt.Errorf("number 3 is not allowed")
}
return i % 3, nil
})
// []int(nil), error("number 3 is not allowed")// Success case
result, err := lo.UniqByErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, error) {
return i % 3, nil
})
// []int{0, 1, 2}, nilSimilar:Prototype:func UniqByErr[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) (U, error)) (Slice, error)GroupByโ
Groups elements by a key computed from each element. The result is a map keyed by the group key with slices of original elements.
groups := lo.GroupBy(
[]int{0, 1, 2, 3, 4, 5},
func(i int) int {
return i % 3
},
)
// map[int][]int{0: {0, 3}, 1: {1, 4}, 2: {2, 5}}Prototype:func GroupBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) map[U]SliceGroupByErrโ
Groups elements by a key computed from each element using an iteratee that can return an error. Stops iteration immediately when an error is encountered. The result is a map keyed by the group key with slices of original elements.
// Error case - stops on first error
result, err := lo.GroupByErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, error) {
if i == 3 {
return 0, fmt.Errorf("number 3 is not allowed")
}
return i % 3, nil
})
// map[int][]int(nil), error("number 3 is not allowed")// Success case
result, err := lo.GroupByErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, error) {
return i % 3, nil
})
// map[int][]int{0: {0, 3}, 1: {1, 4}, 2: {2, 5}}, nilPrototype:func GroupByErr[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) (U, error)) (map[U]Slice, error)TakeFilterโ
Filters elements and takes the first n elements that match the predicate. Equivalent to calling Take(Filter(...)), but more efficient as it stops after finding n matches.
lo.TakeFilter([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 3, func(val int, index int) bool {
return val%2 == 0
})
// []int{2, 4, 6}
lo.TakeFilter([]string{"a", "aa", "aaa", "aaaa"}, 2, func(val string, index int) bool {
return len(val) > 1
})
// []string{"aa", "aaa"}Prototype:func TakeFilter[T any, Slice ~[]T](collection Slice, n int, predicate func(item T, index int) bool) SliceGroupByMapโ
Groups items by a key computed from each element and maps each element to a value.
groups := lo.GroupByMap(
[]int{0, 1, 2, 3, 4, 5},
func(i int) (int, int) {
return i % 3, i * 2
},
)
// map[int][]int{0:{0,6}, 1:{2,8}, 2:{4,10}}Prototype:func GroupByMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K][]VGroupByMapErrโ
Groups items by a key computed from each element and maps each element to a value using a transform function that can return an error. Stops iteration immediately when an error is encountered.
// Error case - stops on first error
result, err := lo.GroupByMapErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, int, error) {
if i == 3 {
return 0, 0, fmt.Errorf("number 3 is not allowed")
}
return i % 3, i * 2, nil
})
// map[int][]int(nil), error("number 3 is not allowed")// Success case
result, err := lo.GroupByMapErr([]int{0, 1, 2, 3, 4, 5}, func(i int) (int, int, error) {
return i % 3, i * 2, nil
})
// map[int][]int{0: {0, 6}, 1: {2, 8}, 2: {4, 10}}, nilPrototype:func GroupByMapErr[T any, K comparable, V any](collection []T, transform func(item T) (K, V, error)) (map[K][]V, error)Chunkโ
Splits a slice into chunks of the given size. The final chunk may be smaller.
lo.Chunk([]int{0, 1, 2, 3, 4, 5}, 2)
// [][]int{{0, 1}, {2, 3}, {4, 5}}
lo.Chunk([]int{0, 1, 2, 3, 4, 5, 6}, 2)
// [][]int{{0, 1}, {2, 3}, {4, 5}, {6}}Note
lo.ChunkStringandlo.Chunkfunctions behave inconsistently for empty input:lo.ChunkString("", n)returns[""]instead of[].Prototype:func Chunk[T any, Slice ~[]T](collection Slice, size int) []SliceWindowโ
Creates a slice of sliding windows of a given size. Each window overlaps with the previous one by size-1 elements. This is equivalent to
Sliding(collection, size, 1).lo.Window([]int{1, 2, 3, 4, 5}, 3)
// [][]int{{1, 2, 3}, {2, 3, 4}, {3, 4, 5}}
lo.Window([]float64{20, 22, 21, 23, 24}, 3)
// [][]float64{{20, 22, 21}, {22, 21, 23}, {21, 23, 24}}Prototype:func Window[T any, Slice ~[]T](collection Slice, size int) []SlicePartitionByโ
Partitions a slice into groups determined by a key computed from each element, preserving original order.
Prototype:func PartitionBy[T any, K comparable, Slice ~[]T](collection Slice, iteratee func(item T) K) []SliceSlidingโ
Creates a slice of sliding windows of a given size with a given step. If step is equal to size, windows don't overlap (similar to Chunk). If step is less than size, windows overlap.
// Overlapping windows (step < size)
lo.Sliding([]int{1, 2, 3, 4, 5, 6}, 3, 1)
// [][]int{{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}
// Non-overlapping windows (step == size, like Chunk)
lo.Sliding([]int{1, 2, 3, 4, 5, 6}, 3, 3)
// [][]int{{1, 2, 3}, {4, 5, 6}}
// Step > size (skipping elements)
lo.Sliding([]int{1, 2, 3, 4, 5, 6, 7, 8}, 2, 3)
// [][]int{{1, 2}, {4, 5}, {7, 8}}Prototype:func Sliding[T any, Slice ~[]T](collection Slice, size, step int) []SlicePartitionByErrโ
Partitions a slice into groups determined by a key computed from each element using an iteratee that can return an error. Stops iteration immediately when an error is encountered. Preserves original order.
// Error case - stops on first error
result, err := lo.PartitionByErr([]int{-2, -1, 0, 1, 2, 3}, func(x int) (string, error) {
if x == 0 {
return "", fmt.Errorf("zero is not allowed")
}
if x < 0 {
return "negative", nil
} else if x%2 == 0 {
return "even", nil
}
return "odd", nil
})
// [][]int(nil), error("zero is not allowed")// Success case
result, err := lo.PartitionByErr([]int{-2, -1, 0, 1, 2}, func(x int) (string, error) {
if x < 0 {
return "negative", nil
} else if x%2 == 0 {
return "even", nil
}
return "odd", nil
})
// [][]int{{-2, -1}, {0, 2}, {1}}, nilPrototype:func PartitionByErr[T any, K comparable, Slice ~[]T](collection Slice, iteratee func(item T) (K, error)) ([]Slice, error)Cloneโ
Returns a shallow copy of the collection.
in := []int{1, 2, 3, 4, 5}
cloned := lo.Clone(in)
// Verify it's a different slice by checking that modifying one doesn't affect the other
in[0] = 99
// cloned is []int{1, 2, 3, 4, 5}Prototype:func Clone[T any, Slice ~[]T](collection Slice) SliceConcatโ
Returns a new slice containing all the elements in collections. Concat conserves the order of the elements.
list1 := []int{0, 1}
list2 := []int{2, 3, 4, 5}
flat := lo.Flatten(list1, list2)
// []int{0, 1, 2, 3, 4, 5}Similar:Prototype:func Concat[T any, Slice ~[]T](collections ...Slice) SliceFlattenโ
Flattens a slice of slices by one level.
flat := lo.Flatten([][]int{{0, 1}, {2, 3, 4, 5}})
// []int{0, 1, 2, 3, 4, 5}Similar:Prototype:func Flatten[T any, Slice ~[]T](collection []Slice) SliceDropโ
Drops n elements from the beginning of a slice.
lo.Drop([]int{0, 1, 2, 3, 4, 5}, 2)
// []int{2, 3, 4, 5}Prototype:func Drop[T any, Slice ~[]T](collection Slice, n int) SliceInterleaveโ
Round-robins input slices by index, appending values sequentially into the result.
lo.Interleave([]int{1, 4, 7}, []int{2, 5, 8}, []int{3, 6, 9})
// []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
lo.Interleave([]int{1}, []int{2, 5, 8}, []int{3, 6}, []int{4, 7, 9, 10})
// []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}Prototype:func Interleave[T any, Slice ~[]T](collections ...Slice) SliceTakeโ
Takes the first n elements from a slice.
lo.Take([]int{0, 1, 2, 3, 4, 5}, 3)
// []int{0, 1, 2}
lo.Take([]int{0, 1, 2}, 5)
// []int{0, 1, 2}Prototype:func Take[T any, Slice ~[]T](collection Slice, n int) SliceDropRightโ
Drops n elements from the end of a slice.
lo.DropRight([]int{0, 1, 2, 3, 4, 5}, 2)
// []int{0, 1, 2, 3}Prototype:func DropRight[T any, Slice ~[]T](collection Slice, n int) SliceShuffleโ
Returns a slice of shuffled values (FisherโYates). Deprecated: use
mutable.Shuffle.Prototype:func Shuffle[T any, Slice ~[]T](collection Slice) SliceDropWhileโ
Drops elements from the beginning while the predicate returns true.
lo.DropWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string) bool {
return len(val) <= 2
})
// []string{"aaa", "aa", "aa"}Prototype:func DropWhile[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) SliceReverseโ
Reverses a slice in place. Deprecated: use
mutable.Reverse.Prototype:func Reverse[T any, Slice ~[]T](collection Slice) SliceTakeWhileโ
Takes elements from the beginning while the predicate returns true.
lo.TakeWhile([]int{0, 1, 2, 3, 4, 5}, func(val int) bool {
return val < 3
})
// []int{0, 1, 2}
lo.TakeWhile([]string{"a", "aa", "aaa", "aa"}, func(val string) bool {
return len(val) <= 2
})
// []string{"a", "aa"}Prototype:func TakeWhile[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) SliceDropRightWhileโ
Drops elements from the end while the predicate returns true.
lo.DropRightWhile([]string{"a", "aa", "aaa", "aa", "aa"}, func(val string) bool {
return len(val) <= 2
})
// []string{"a", "aa", "aaa"}Prototype:func DropRightWhile[T any, Slice ~[]T](collection Slice, predicate func(item T) bool) SliceFillโ
Fills a slice with clones of the provided initial value.
type foo struct{ bar string }
func (f foo) Clone() foo {
return foo{f.bar}
}
lo.Fill([]foo{{"a"}, {"a"}}, foo{"b"})
// []foo{{"b"}, {"b"}}Prototype:func Fill[T Clonable[T], Slice ~[]T](collection Slice, initial T) SliceDropByIndexโ
Drops elements from a slice by index. Negative indexes count from the end.
lo.DropByIndex([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1)
// []int{0, 1, 3}Prototype:func DropByIndex[T any, Slice ~[]T](collection Slice, indexes ...int) SliceRepeatโ
Builds a slice with N copies of initial value.
lo.Repeat(5, "42")
// []string{"42", "42", "42", "42", "42"}Prototype:func Repeat[T any](count int, initial T) []TRepeatByโ
Builds a slice by calling the callback N times with the current index.
lo.RepeatBy(5, func(i int) string {
return strconv.Itoa(i * i)
})
// []string{"0", "1", "4", "9", "16"}Variant:Prototype:func RepeatBy[T any](count int, callback func(index int) T) []TRepeatByErrโ
Builds a slice by calling the callback N times with the current index. The callback can return an error to stop iteration immediately.
result, err := lo.RepeatByErr(5, func(i int) (int, error) {
return i * i, nil
})
// []int{0, 1, 4, 9, 16}, <nil>Example with error:
result, err := lo.RepeatByErr(5, func(i int) (int, error) {
if i == 3 {
return 0, fmt.Errorf("number 3 is not allowed")
}
return i * i, nil
})
// []int(nil), error("number 3 is not allowed")Prototype:func RepeatByErr[T any](count int, callback func(index int) (T, error)) ([]T, error)KeyByโ
Transforms a slice to a map using a pivot callback to compute keys.
m := lo.KeyBy(
[]string{"a", "aa", "aaa"},
func(str string) int {
return len(str)
},
)
// map[int]string{1: "a", 2: "aa", 3: "aaa"}Prototype:func KeyBy[K comparable, V any](collection []V, iteratee func(item V) K) map[K]VKeyByErrโ
Transforms a slice to a map using a pivot callback to compute keys. Stops iteration immediately when an error is encountered.
// Error case - stops on first error
result, err := lo.KeyByErr([]string{"a", "aa", "aaa", ""}, func(str string) (int, error) {
if str == "" {
return 0, fmt.Errorf("empty string not allowed")
}
return len(str), nil
})
// map[int]string(nil), error("empty string not allowed")// Success case
result, err := lo.KeyByErr([]string{"a", "aa", "aaa"}, func(str string) (int, error) {
if str == "" {
return 0, fmt.Errorf("empty string not allowed")
}
return len(str), nil
})
// map[int]string{1: "a", 2: "aa", 3: "aaa"}, nilPrototype:func KeyByErr[K comparable, V any](collection []V, iteratee func(item V) (K, error)) (map[K]V, error)Associateโ
Builds a map from a slice using a transform function that yields key/value pairs for each item. Perfect for converting collections to lookup maps.
Associate
Transforms each element into a key-value pair. Later items with the same key will overwrite earlier ones.
type foo struct {
baz string
bar int
}
in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}}
m := lo.Associate(in, func(f *foo) (string, int) {
return f.baz, f.bar
})
// m: map[string]int{"apple": 1, "banana": 2}AssociateI
Variant that includes the element index in the transform function, useful when you need the position in the original slice.
type User struct {
Name string
Age int
}
users := []User{
{Name: "Alice", Age: 25},
{Name: "Bob", Age: 30},
}
result := lo.AssociateI(users, func(user User, index int) (string, int) {
return fmt.Sprintf("%s-%d", user.Name, index), user.Age
})
// result: map[string]int{"Alice-0": 25, "Bob-1": 30}SliceToMap
Alias for Associate - provides the same functionality with a more explicit name.
products := []string{"apple", "banana", "cherry"}
result := lo.SliceToMap(products, func(product string) (string, int) {
return product, len(product)
})
// result: map[string]int{"apple": 5, "banana": 6, "cherry": 6}Variant:Prototypes:func Associate[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]V
func AssociateI[T any, K comparable, V any](collection []T, transform func(item T, index int) (K, V)) map[K]V
func SliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]VSliceToMapโ
Alias of Associate: transforms a slice into a map using a key/value transform function.
type foo struct {
baz string
bar int
}
in := []*foo{{baz: "apple", bar: 1}, {baz: "banana", bar: 2}}
m := lo.SliceToMap(in, func(f *foo) (string, int) {
return f.baz, f.bar
})
// map[string]int{"apple": 1, "banana": 2}Variant:Prototypes:func SliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]V
func Associate[T any, K comparable, V any](collection []T, transform func(item T) (K, V)) map[K]V
func AssociateI[T any, K comparable, V any](collection []T, transform func(item T, index int) (K, V)) map[K]VFilterSliceToMapโ
Transforms elements to key/value pairs and includes them in the result only when the transform's boolean is true.
list := []string{"a", "aa", "aaa"}
m := lo.FilterSliceToMap(list, func(str string) (string, int, bool) {
return str, len(str), len(str) > 1
})
// map[string]int{"aa": 2, "aaa": 3}Prototype:func FilterSliceToMap[T any, K comparable, V any](collection []T, transform func(item T) (K, V, bool)) map[K]VRejectโ
Returns the elements for which the predicate returns false (opposite of Filter).
lo.Reject(
[]int{1, 2, 3, 4},
func(x int, _ int) bool {
return x%2 == 0
},
)
// []int{1, 3}Prototype:func Reject[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) SliceRejectErrโ
The opposite of FilterErr. Returns the elements for which the predicate returns false. If the predicate returns an error, iteration stops immediately and returns the error.
odd, err := lo.RejectErr([]int{1, 2, 3, 4}, func(x int, index int) (bool, error) {
if x == 3 {
return false, errors.New("number 3 is not allowed")
}
return x%2 == 0, nil
})
// []int(nil), error("number 3 is not allowed")odd, err := lo.RejectErr([]int{1, 2, 3, 4}, func(x int, index int) (bool, error) {
return x%2 == 0, nil
})
// []int{1, 3}, nilPrototype:func RejectErr[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) (bool, error)) (Slice, error)Compactโ
Returns a slice of all non-zero elements.
lo.Compact([]string{"", "foo", "", "bar", ""})
// []string{"foo", "bar"}Similar:Prototype:func Compact[T comparable, Slice ~[]T](collection Slice) SliceKeyifyโ
Returns a set-like map where each unique element of the slice is a key.
set := lo.Keyify([]int{1, 1, 2, 3, 4})
// map[int]struct{}{1: {}, 2: {}, 3: {}, 4: {}}Prototype:func Keyify[T comparable, Slice ~[]T](collection Slice) map[T]struct{}RejectMapโ
Opposite of FilterMap: maps each item and includes results where the predicate returned false.
items := lo.RejectMap([]int{1, 2, 3, 4}, func(x int, _ int) (int, bool) {
return x * 10, x%2 == 0
})
// []int{10, 30}Prototype:func RejectMap[T any, R any](collection []T, callback func(item T, index int) (R, bool)) []RFilterRejectโ
Returns two slices: elements kept (predicate true) and elements rejected (predicate false).
kept, rejected := lo.FilterReject(
[]int{1, 2, 3, 4},
func(x int, _ int) bool {
return x%2 == 0
},
)
// kept: []int{2, 4}
// rejected: []int{1, 3}Prototype:func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bool) (kept Slice, rejected Slice)