MCPcopy
hub / github.com/samber/lo

github.com/samber/lo @v1.53.0 sqlite

repository ↗ · DeepWiki ↗ · release v1.53.0 ↗
1,500 symbols 3,555 edges 55 files 988 documented · 66%
README

lo - Iterate over slices, maps, channels...

tag Go Version GoDoc Build Status Go report Coverage Contributors License

samber/lo is a Lodash-style Go library based on Go 1.18+ Generics.

A utility library based on Go 1.18+ generics that makes it easier to work with slices, maps, strings, channels, and functions. It provides dozens of handy methods to simplify common coding tasks and improve code readability. It may look like Lodash in some aspects.

5 to 10 helpers may overlap with those from the Go standard library, in packages slices and maps. I feel this library is legitimate and offers many more valuable abstractions.

See also:

  • samber/ro: Reactive Programming for Go: declarative and composable API for event-driven applications
  • samber/do: A dependency injection toolkit based on Go 1.18+ Generics
  • samber/mo: Monads based on Go 1.18+ Generics (Option, Result, Either...)

What makes it different from samber/ro? - lo: synchronous helpers across finite sequences (maps, slices...) - ro: processing of infinite data streams for event-driven scenarios


💖 Sponsored by:

  <img width="200" alt="dbos" src="https://github.com/user-attachments/assets/d583cb62-7735-4d3c-beb7-e6ef1a5faf49" />






  DBOS - Durable workflow orchestration library for Go


Why this name?

I wanted a short name, similar to "Lodash", and no Go package uses this name.

lo

🚀 Install

go get github.com/samber/lo@v1

This library is v1 and follows SemVer strictly.

No breaking changes will be made to exported APIs before v2.0.0, except for experimental packages under exp/.

This library has no dependencies outside the Go standard library.

💡 Usage

You can import lo using:

import (
    "github.com/samber/lo"
    lop "github.com/samber/lo/parallel"
    lom "github.com/samber/lo/mutable"
    loi "github.com/samber/lo/it"
)

Then use one of the helpers below:

names := lo.Uniq([]string{"Samuel", "John", "Samuel"})
// []string{"Samuel", "John"}

Tips for lazy developers

I cannot recommend it, but in case you are too lazy for repeating lo. everywhere, you can import the entire library into the namespace.

import (
    . "github.com/samber/lo"
)

I take no responsibility for this junk. 😁 💩

🤠 Spec

GoDoc: godoc.org/github.com/samber/lo

Documentation: lo.samber.dev

Supported helpers for slices:

Supported helpers for maps:

Supported math helpers:

Supported helpers for strings:

Supported helpers for tuples:

Supported helpers for time and duration:

Supported helpers for channels:

Supported intersection helpers:

Supported search helpers:

Conditional helpers:

Type manipulation helpers:

Function helpers:

Concurrency helpers:

Error handling:

Constraints:

  • Clonable

Filter

Iterates over a collection and returns a slice of all the elements the predicate function returns true for.

even := lo.Filter([]int{1, 2, 3, 4}, func(x int, index int) bool {
    return x%2 == 0
})
// []int{2, 4}
// Use FilterErr when the predicate can return an error
even, err := lo.FilterErr([]int{1, 2, 3, 4}, func(x int, _ int) (bool, error) {
    if x == 3 {
        return false, fmt.Errorf("number 3 is not allowed")
    }
    return x%2 == 0, nil
})
// []int(nil), error("number 3 is not allowed")

[play]

Mutable: like lo.Filter(), but the slice is updated in place.

import lom "github.com/samber/lo/mutable"

list := []int{1, 2, 3, 4}
newList := lom.Filter(list, func(x int) bool {
    return x%2 == 0
})

list
// []int{2, 4, 3, 4}

newList
// []int{2, 4}

Map

Manipulates a slice of one type and transforms it into a slice of another type:

import "github.com/samber/lo"

lo.Map([]int64{1, 2, 3, 4}, func(x int64, index int) string {
    return strconv.FormatInt(x, 10)
})
// []string{"1", "2", "3", "4"}
// Use MapErr when the transform function can return an 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")

[play]

Parallel processing: like lo.Map(), but the transform function is called in a goroutine. Results are returned in the same order.

import lop "github.com/samber/lo/parallel"

lop.Map([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
    return strconv.FormatInt(x, 10)
})
// []string{"1", "2", "3", "4"}

[play]

Mutable: like lo.Map(), but the slice is updated in place.

import lom "github.com/samber/lo/mutable"

list := []int{1, 2, 3, 4}
lom.Map(list, func(x int) int {
    return x*2
})
// []int{2, 4, 6, 8}

[play]

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"}

[play]

FilterMap

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"}

[play]

FlatMap

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 the nil case no value is added to the final slice.

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"}

```go // Use FlatMapErr when the transform function can return an error result, err := lo.FlatMapErr([]int64{0, 1, 2, 3}, func(x int64, _ int) ([]string, error) { if x == 2 { return n

Extension points exported contracts — how you extend this code

Clonable (Interface)
Clonable defines a constraint of types having Clone() T method.
constraints.go
DispatchingStrategy (FuncType)
DispatchingStrategy is a function that distributes messages to channels.
channel.go
Signed (Interface)
Signed is a constraint that permits any signed integer type. If future releases of Go add new predeclared signed integer
internal/constraints/constraints.go
Clock (Interface)
(no doc) [2 implementers]
internal/xtime/time.go
Unsigned (Interface)
Unsigned is a constraint that permits any unsigned integer type. If future releases of Go add new predeclared unsigned i
internal/constraints/constraints.go
Integer (Interface)
Integer is a constraint that permits any integer type. If future releases of Go add new predeclared integer types, this
internal/constraints/constraints.go
Float (Interface)
Float is a constraint that permits any floating-point type. If future releases of Go add new predeclared floating-point
internal/constraints/constraints.go
Complex (Interface)
Complex is a constraint that permits any complex numeric type. If future releases of Go add new predeclared complex nume
internal/constraints/constraints.go

Core symbols most depended-on inside this repo

NthOrEmpty
called by 134
find.go
Map
called by 64
slice.go
Max
called by 36
find.go
Case
called by 30
condition.go
CaseF
called by 30
condition.go
Now
called by 27
internal/xtime/time.go
Keyify
called by 24
slice.go
Since
called by 21
internal/xtime/time.go

Shape

Function 1,420
Method 41
Struct 28
Interface 8
FuncType 2
TypeAlias 1

Languages

Go100%

Modules by API surface

lo_example_test.go287 symbols
tuples.go88 symbols
slice.go80 symbols
it/seq.go78 symbols
exp/simd/math_avx512.go76 symbols
exp/simd/math_avx2.go70 symbols
exp/simd/math.go70 symbols
exp/simd/math_avx.go64 symbols
it/seq_example_test.go58 symbols
it/find_example_test.go52 symbols
find.go49 symbols
it/find.go38 symbols

Dependencies from manifests, versioned

golang.org/x/textv0.22.0 · 1×

For agents

$ claude mcp add lo \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact