Skip to main content
Help improve this documentation

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!

Parallel - Slice helpersโ€‹

This page lists all operations on slices, available in the parallel lo sub-package.

  • Manipulates a slice and transforms it into a slice of another type. The predicate is called in parallel and results are written back in the original order.

    import (
    "strconv"
    lop "github.com/samber/lo/parallel"
    )

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

    Parallel execution is useful when the predicate is slow or I/O-bound:

    import (
    "net/http"
    "io"
    lop "github.com/samber/lo/parallel"
    )

    urls := []string{"https://example.com/a", "https://example.com/b"}
    pages := lop.Map(urls, func(u string, _ int) string {
    resp, _ := http.Get(u)
    defer resp.Body.Close()
    b, _ := io.ReadAll(resp.Body)
    return string(b)
    })
    // pages keeps the same order as urls
    Prototype:
    func Map[T any, R any](collection []T, iteratee func(item T, index int) R) []R
  • Iterates over elements of a collection and invokes the predicate for each element. The predicate is called in parallel.

    import (
    "fmt"
    lop "github.com/samber/lo/parallel"
    )

    lop.ForEach([]string{"hello", "world"}, func(x string, _ int) {
    fmt.Println(x)
    })
    // prints lines in any order depending on scheduling

    Useful for fire-and-forget work like publishing events or independent side effects:

    type Job struct{ ID int }

    jobs := []Job{{1}, {2}, {3}}
    lop.ForEach(jobs, func(j Job, _ int) {
    // process each job concurrently
    // send(j)
    })
    Prototype:
    func ForEach[T any](collection []T, iteratee func(item T, index int))
  • Invokes the predicate count times, returning a slice of the results of each invocation. The predicate is called in parallel with the index as argument.

    import (
    "strconv"
    lop "github.com/samber/lo/parallel"
    )

    nums := lop.Times(5, func(i int) string {
    return strconv.Itoa(i)
    })
    // []string{"0", "1", "2", "3", "4"}

    Great for generating data concurrently:

    ids := lop.Times(10, func(i int) string {
    return fmt.Sprintf("item-%d", i)
    })
    Prototype:
    func Times[T any](count int, iteratee func(index int) T) []T
  • Returns a map composed of keys generated from the results of running each element of the collection through the predicate. The predicate is called in parallel. Values keep the input order within each group.

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

    groups := lop.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}}

    Custom key types work as long as they are comparable:

    type Kind string
    groups2 := lop.GroupBy([]string{"go", "rust", "java"}, func(s string) Kind {
    if len(s) <= 2 { return "short" }
    return "long"
    })
    // map[Kind][]string{"short": {"go"}, "long": {"rust", "java"}}
    Prototype:
    func GroupBy[T any, U comparable, Slice ~[]T](collection Slice, iteratee func(item T) U) map[U]Slice
  • Returns a slice of groups where contiguous elements sharing the same key are batched together. Groups are created from the results of running each element of the collection through the predicate. The predicate is called in parallel and the order of groups follows their first appearance in the collection.

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

    groups := lop.PartitionBy([]int{-2, -1, 0, 1, 2, 3, 4, 5}, func(x int) string {
    if x < 0 { return "negative" }
    if x%2 == 0 { return "even" }
    return "odd"
    })
    // [][]int{{-2, -1}, {0, 2, 4}, {1, 3, 5}}

    Works with any comparable key type:

    type Bucket int
    parts := lop.PartitionBy([]int{1,2,2,3,3,3}, func(x int) Bucket {
    return Bucket(x)
    })
    // [][]int{{1}, {2,2}, {3,3,3}}
    Prototype:
    func PartitionBy[T any, K comparable, Slice ~[]T](collection Slice, iteratee func(item T) K) []Slice