fn: add concurrent map operation for slices

This commit is contained in:
Keagan McClelland committed 2024-07-10 15:29:16 -07:00
1 parent 94acbe90a8
commit 5902aa5159
2 files changed
+96 -1

No files matched your search

+37 -1
View File
@@ -1,6 +1,13 @@
package fn
import "golang.org/x/exp/constraints"
import (
"context"
"runtime"
"sync"
"golang.org/x/exp/constraints"
"golang.org/x/sync/semaphore"
)
// Number is a type constraint for all numeric types in Go (integers,
// float and complex numbers)
@@ -205,3 +212,32 @@ func Sum[B Number](items []B) B {
func HasDuplicates[A comparable](items []A) bool {
return len(NewSet(items...)) != len(items)
}
// ForEachConc maps the argument function over the slice, spawning a new
// goroutine for each element in the slice and then awaits all results before
// returning them.
func ForEachConc[A, B any](f func(A) B,
as []A) []B {
var wait sync.WaitGroup
ctx := context.Background()
sem := semaphore.NewWeighted(int64(runtime.NumCPU()))
bs := make([]B, len(as))
for i, a := range as {
i, a := i, a
sem.Acquire(ctx, 1)
wait.Add(1)
go func() {
bs[i] = f(a)
wait.Done()
sem.Release(1)
}()
}
wait.Wait()
return bs
}