mirror of
https://github.com/samber/lo.git
synced 2026-04-22 15:37:14 +08:00
feat: adding "mutable" subpackage
This commit is contained in:
@@ -48,6 +48,7 @@ You can import `lo` using:
|
||||
import (
|
||||
"github.com/samber/lo"
|
||||
lop "github.com/samber/lo/parallel"
|
||||
lom "github.com/samber/lo/mutable"
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package mutable
|
||||
|
||||
import "math/rand"
|
||||
|
||||
// Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for.
|
||||
// The function returns the modified slice, which may be shorter than the original if some elements were removed.
|
||||
// The order of elements in the original slice is preserved in the output.
|
||||
// Play:
|
||||
func Filter[T any](collection *[]T, predicate func(item T) bool) {
|
||||
FilterI(collection, func(item T, index int) bool {
|
||||
return predicate(item)
|
||||
})
|
||||
}
|
||||
|
||||
// Filter iterates over elements of collection, returning an array of all elements predicate returns truthy for.
|
||||
// The function returns the modified slice, which may be shorter than the original if some elements were removed.
|
||||
// The order of elements in the original slice is preserved in the output.
|
||||
// Play:
|
||||
func FilterI[T any](collection *[]T, predicate func(item T, index int) bool) {
|
||||
j := 0
|
||||
for i := range *collection {
|
||||
if predicate((*collection)[i], i) {
|
||||
(*collection)[j] = (*collection)[i]
|
||||
j++
|
||||
}
|
||||
}
|
||||
|
||||
*collection = (*collection)[:j]
|
||||
}
|
||||
|
||||
// Uniq returns a duplicate-free version of an array, in which only the first occurrence of each element is kept.
|
||||
// The order of result values is determined by the order they occur in the array.
|
||||
// Play:
|
||||
func Uniq[T comparable](collection *[]T) {
|
||||
size := len(*collection)
|
||||
seen := make(map[T]struct{}, size)
|
||||
j := 0
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
if _, ok := seen[(*collection)[i]]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
seen[(*collection)[i]] = struct{}{}
|
||||
|
||||
(*collection)[j] = (*collection)[i]
|
||||
j++
|
||||
}
|
||||
|
||||
*collection = (*collection)[:j]
|
||||
}
|
||||
|
||||
// UniqBy returns a duplicate-free version of an array, in which only the first occurrence of each element is kept.
|
||||
// The order of result values is determined by the order they occur in the array. It accepts `iteratee` which is
|
||||
// invoked for each element in array to generate the criterion by which uniqueness is computed.
|
||||
// Play:
|
||||
func UniqBy[T any, U comparable](collection *[]T, iteratee func(item T) U) {
|
||||
size := len(*collection)
|
||||
seen := make(map[U]struct{}, size)
|
||||
j := 0
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
key := iteratee((*collection)[i])
|
||||
if _, ok := seen[key]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
seen[key] = struct{}{}
|
||||
|
||||
(*collection)[j] = (*collection)[i]
|
||||
j++
|
||||
}
|
||||
|
||||
*collection = (*collection)[:j]
|
||||
}
|
||||
|
||||
// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
|
||||
// Play:
|
||||
func Shuffle[T any](collection []T) {
|
||||
rand.Shuffle(len(collection), func(i, j int) {
|
||||
collection[i], collection[j] = collection[j], collection[i]
|
||||
})
|
||||
}
|
||||
|
||||
// Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.
|
||||
// Play:
|
||||
func Reverse[T any](collection []T) {
|
||||
length := len(collection)
|
||||
half := length / 2
|
||||
|
||||
for i := 0; i < half; i = i + 1 {
|
||||
j := length - 1 - i
|
||||
collection[i], collection[j] = collection[j], collection[i]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package mutable
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
r1 := []int{1, 2, 3, 4}
|
||||
Filter(&r1, func(x int) bool {
|
||||
return x%2 == 0
|
||||
})
|
||||
is.Equal([]int{2, 4}, r1)
|
||||
|
||||
r2 := []string{"", "foo", "", "bar", ""}
|
||||
Filter(&r2, func(x string) bool {
|
||||
return len(x) > 0
|
||||
})
|
||||
is.Equal([]string{"foo", "bar"}, r2)
|
||||
}
|
||||
|
||||
func TestFilterI(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
r1 := []int{1, 2, 3, 4}
|
||||
FilterI(&r1, func(x int, _ int) bool {
|
||||
return x%2 == 0
|
||||
})
|
||||
is.Equal([]int{2, 4}, r1)
|
||||
|
||||
r2 := []string{"", "foo", "", "bar", ""}
|
||||
FilterI(&r2, func(x string, _ int) bool {
|
||||
return len(x) > 0
|
||||
})
|
||||
is.Equal([]string{"foo", "bar"}, r2)
|
||||
}
|
||||
|
||||
func TestUniq(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := []int{1, 2, 2, 1}
|
||||
Uniq(&result1)
|
||||
is.Equal(len(result1), 2)
|
||||
is.Equal(result1, []int{1, 2})
|
||||
}
|
||||
|
||||
func TestUniqBy(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := []int{0, 1, 2, 3, 4, 5}
|
||||
UniqBy(&result1, func(i int) int {
|
||||
return i % 3
|
||||
})
|
||||
|
||||
is.Equal(len(result1), 3)
|
||||
is.Equal(result1, []int{0, 1, 2})
|
||||
}
|
||||
|
||||
func TestShuffle(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
Shuffle(result1)
|
||||
is.NotEqual(result1, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
|
||||
result2 := []int{}
|
||||
Shuffle(result2)
|
||||
is.Equal(result2, []int{})
|
||||
}
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := []int{0, 1, 2, 3, 4, 5}
|
||||
Reverse(result1)
|
||||
is.Equal(result1, []int{5, 4, 3, 2, 1, 0})
|
||||
|
||||
result2 := []int{0, 1, 2, 3, 4, 5, 6}
|
||||
Reverse(result2)
|
||||
is.Equal(result2, []int{6, 5, 4, 3, 2, 1, 0})
|
||||
|
||||
result3 := []int{}
|
||||
Reverse(result3)
|
||||
is.Equal(result3, []int{})
|
||||
}
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
package parallel
|
||||
|
||||
import "sync"
|
||||
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.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package lo
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"math/rand"
|
||||
"sort"
|
||||
|
||||
"github.com/samber/lo/internal/constraints"
|
||||
)
|
||||
@@ -273,15 +273,21 @@ func Interleave[T any, Slice ~[]T](collections ...Slice) Slice {
|
||||
// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
|
||||
// Play: https://go.dev/play/p/Qp73bnTDnc7
|
||||
func Shuffle[T any, Slice ~[]T](collection Slice) Slice {
|
||||
rand.Shuffle(len(collection), func(i, j int) {
|
||||
collection[i], collection[j] = collection[j], collection[i]
|
||||
size := len(collection)
|
||||
output := make(Slice, size)
|
||||
copy(output, collection)
|
||||
|
||||
rand.Shuffle(size, func(i, j int) {
|
||||
output[i], output[j] = output[j], output[i]
|
||||
})
|
||||
|
||||
return collection
|
||||
return output
|
||||
}
|
||||
|
||||
// Reverse reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.
|
||||
// Play: https://go.dev/play/p/fhUMLvZ7vS6
|
||||
//
|
||||
// Deprecated: Use lom.Reverse instead.
|
||||
func Reverse[T any, Slice ~[]T](collection Slice) Slice {
|
||||
length := len(collection)
|
||||
half := length / 2
|
||||
|
||||
+6
-3
@@ -335,10 +335,13 @@ func TestShuffle(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := Shuffle([]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
result2 := Shuffle([]int{})
|
||||
|
||||
input1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||
result1 := Shuffle(input1)
|
||||
is.Equal(input1, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
is.NotEqual(result1, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
|
||||
input2 := []int{}
|
||||
result2 := Shuffle(input2)
|
||||
is.Equal(result2, []int{})
|
||||
|
||||
type myStrings []string
|
||||
|
||||
Reference in New Issue
Block a user