1 package iter
2 3 import (
4 "sync"
5 6 "github.com/sourcegraph/conc/internal/multierror"
7 )
8 9 // Mapper is an Iterator with a result type R. It can be used to configure
10 // the behaviour of Map and MapErr. The zero value is safe to use with
11 // reasonable defaults.
12 //
13 // Mapper is also safe for reuse and concurrent use.
14 type Mapper[T, R any] Iterator[T]
15 16 // Map applies f to each element of input, returning the mapped result.
17 //
18 // Map always uses at most runtime.GOMAXPROCS goroutines. For a configurable
19 // goroutine limit, use a custom Mapper.
20 func Map[T, R any](input []T, f func(*T) R) []R {
21 return Mapper[T, R]{}.Map(input, f)
22 }
23 24 // Map applies f to each element of input, returning the mapped result.
25 //
26 // Map uses up to the configured Mapper's maximum number of goroutines.
27 func (m Mapper[T, R]) Map(input []T, f func(*T) R) []R {
28 res := make([]R, len(input))
29 Iterator[T](m).ForEachIdx(input, func(i int, t *T) {
30 res[i] = f(t)
31 })
32 return res
33 }
34 35 // MapErr applies f to each element of the input, returning the mapped result
36 // and a combined error of all returned errors.
37 //
38 // Map always uses at most runtime.GOMAXPROCS goroutines. For a configurable
39 // goroutine limit, use a custom Mapper.
40 func MapErr[T, R any](input []T, f func(*T) (R, error)) ([]R, error) {
41 return Mapper[T, R]{}.MapErr(input, f)
42 }
43 44 // MapErr applies f to each element of the input, returning the mapped result
45 // and a combined error of all returned errors.
46 //
47 // Map uses up to the configured Mapper's maximum number of goroutines.
48 func (m Mapper[T, R]) MapErr(input []T, f func(*T) (R, error)) ([]R, error) {
49 var (
50 res = make([]R, len(input))
51 errMux sync.Mutex
52 errs error
53 )
54 Iterator[T](m).ForEachIdx(input, func(i int, t *T) {
55 var err error
56 res[i], err = f(t)
57 if err != nil {
58 errMux.Lock()
59 // TODO: use stdlib errors once multierrors land in go 1.20
60 errs = multierror.Join(errs, err)
61 errMux.Unlock()
62 }
63 })
64 return res, errs
65 }
66