mirror of
https://github.com/samber/lo.git
synced 2025-09-26 20:11:13 +08:00
adding lop.Map and lop.ForEach
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 1.2.0 (2022-03-03)
|
||||
|
||||
Adding `lop.Map` and `lop.ForEach`.
|
||||
|
||||
## 1.1.0 (2022-03-03)
|
||||
|
||||
Adding `i int` param to `lo.Map()`, `lo.Filter()`, `lo.ForEach()` and `lo.Reduce()` predicates.
|
||||
|
10
Makefile
10
Makefile
@@ -7,15 +7,15 @@ go1.18beta1:
|
||||
go1.18beta1 download
|
||||
|
||||
build:
|
||||
${BIN} build -v .
|
||||
${BIN} build -v ./...
|
||||
|
||||
test:
|
||||
go test -v .
|
||||
watch-test: tools
|
||||
reflex -R assets.go -t 50ms -s -- sh -c 'gotest -v .'
|
||||
go test -v ./...
|
||||
watch-test:
|
||||
reflex -R assets.go -t 50ms -s -- sh -c 'gotest -v ./...'
|
||||
|
||||
bench:
|
||||
gotest -benchmem -bench .
|
||||
gotest -benchmem -bench ./...
|
||||
|
||||
coverage:
|
||||
${BIN} test -v -coverprofile cover.out .
|
||||
|
31
README.md
31
README.md
@@ -27,7 +27,10 @@ go get github.com/samber/lo
|
||||
You can import `lo` using a basic statement:
|
||||
|
||||
```go
|
||||
import "github.com/samber/lo"
|
||||
import (
|
||||
"github.com/samber/lo"
|
||||
lop "github.com/samber/lo/parallel"
|
||||
)
|
||||
```
|
||||
|
||||
Then use one of the helpers below:
|
||||
@@ -101,12 +104,25 @@ Constraints:
|
||||
Manipulates a slice and transforms it to a slice of another type:
|
||||
|
||||
```go
|
||||
import "github.com/samber/lo"
|
||||
|
||||
lo.Map[int64, string]([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
|
||||
return strconv.FormatInt(x, 10)
|
||||
})
|
||||
// []string{"1", "2", "3", "4"}
|
||||
```
|
||||
|
||||
Parallel processing: like lo.Map(), but mapper is called in goroutine. Results are returns in the same order.
|
||||
|
||||
```go
|
||||
import lop "github.com/samber/lo/parallel"
|
||||
|
||||
lop.Map[int64, string]([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
|
||||
return strconv.FormatInt(x, 10)
|
||||
}, 2)
|
||||
// []string{"1", "2", "3", "4"}
|
||||
```
|
||||
|
||||
### Filter
|
||||
|
||||
Iterates over elements of collection, returning an array of all elements predicate returns truthy for.
|
||||
@@ -146,7 +162,18 @@ Iterates over elements of collection and invokes iteratee for each element.
|
||||
lo.ForEach[string]([]string{"hello", "world"}, func(x string, _ int) {
|
||||
println(x)
|
||||
})
|
||||
// prints "hello\nworld"
|
||||
// prints "hello\nworld\n"
|
||||
```
|
||||
|
||||
Parallel processing: like lo.ForEach(), but callback is called in goroutine.
|
||||
|
||||
```go
|
||||
import lop "github.com/samber/lo/parallel"
|
||||
|
||||
lop.ForEach[string]([]string{"hello", "world"}, func(x string, _ int) {
|
||||
println(x)
|
||||
})
|
||||
// prints "hello\nworld\n" or "world\nhello\n"
|
||||
```
|
||||
|
||||
### Uniq
|
||||
|
7
go.mod
7
go.mod
@@ -5,10 +5,7 @@ go 1.18
|
||||
require github.com/stretchr/testify v1.7.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
)
|
||||
|
16
go.sum
16
go.sum
@@ -1,21 +1,11 @@
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
45
parallel/slice.go
Normal file
45
parallel/slice.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package parallel
|
||||
|
||||
import "sync"
|
||||
|
||||
// Map manipulates a slice and transforms it to a slice of another type.
|
||||
// `iteratee` is call in parallel. Result keep the same order.
|
||||
func Map[T any, R any](collection []T, iteratee func(T, int) R) []R {
|
||||
result := make([]R, len(collection))
|
||||
|
||||
var mu sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(collection))
|
||||
|
||||
for i, item := range collection {
|
||||
go func (_item T, _i int) {
|
||||
res := iteratee(_item, _i)
|
||||
|
||||
mu.Lock()
|
||||
result[_i] = res
|
||||
mu.Unlock()
|
||||
|
||||
wg.Done()
|
||||
}(item, i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// ForEach iterates over elements of collection and invokes iteratee for each element.
|
||||
// `iteratee` is call in parallel.
|
||||
func ForEach[T any](collection []T, iteratee func(T, int)) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(collection))
|
||||
|
||||
for i, item := range collection {
|
||||
go func (_item T, _i int) {
|
||||
iteratee(_item, _i)
|
||||
wg.Done()
|
||||
}(item, i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
24
parallel/slice_test.go
Normal file
24
parallel/slice_test.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package parallel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"strconv"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := Map[int, string]([]int{1, 2, 3, 4}, func(x int, _ int) string {
|
||||
return "Hello"
|
||||
})
|
||||
result2 := Map[int64, string]([]int64{1, 2, 3, 4}, func(x int64, _ int) string {
|
||||
return strconv.FormatInt(x, 10)
|
||||
})
|
||||
|
||||
is.Equal(len(result1), 4)
|
||||
is.Equal(len(result2), 4)
|
||||
is.Equal(result1, []string{"Hello", "Hello", "Hello", "Hello"})
|
||||
is.Equal(result2, []string{"1", "2", "3", "4"})
|
||||
}
|
Reference in New Issue
Block a user