mirror of
https://github.com/samber/lo.git
synced 2025-11-01 20:12:44 +08:00
@@ -2,6 +2,13 @@
|
||||
|
||||
@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade.
|
||||
|
||||
## 1.21.0 (2022-05-10)
|
||||
|
||||
Adding:
|
||||
|
||||
- lo.ToAnySlice
|
||||
- lo.FromAnySlice
|
||||
|
||||
## 1.20.0 (2022-05-02)
|
||||
|
||||
Adding:
|
||||
|
||||
37
README.md
37
README.md
@@ -77,7 +77,6 @@ Supported helpers for slices:
|
||||
- Reject
|
||||
- Count
|
||||
- CountBy
|
||||
- ToInterfaceSlice
|
||||
|
||||
Supported helpers for maps:
|
||||
|
||||
@@ -144,13 +143,18 @@ Supported search helpers:
|
||||
- Sample
|
||||
- Samples
|
||||
|
||||
Other functional programming helpers:
|
||||
Conditional helpers:
|
||||
|
||||
- Ternary (1 line if/else statement)
|
||||
- If / ElseIf / Else
|
||||
- Switch / Case / Default
|
||||
|
||||
Type manipulation helpers:
|
||||
|
||||
- ToPtr
|
||||
- ToSlicePtr
|
||||
- ToAnySlice
|
||||
- FromAnySlice
|
||||
- Empty
|
||||
- Coalesce
|
||||
|
||||
@@ -636,14 +640,6 @@ slice := lo.ReplaceAll(in, -1, 42)
|
||||
// []int{0, 1, 0, 1, 2, 3, 0}
|
||||
```
|
||||
|
||||
### ToAnySlice
|
||||
|
||||
Returns a slice with all elements mapped to any type
|
||||
```go
|
||||
elements := lo.ToAnySlice[int]([]int{1, 5, 1})
|
||||
// []any{1, 5, 1}
|
||||
```
|
||||
|
||||
### Keys
|
||||
|
||||
Creates an array of the map keys.
|
||||
@@ -1336,6 +1332,27 @@ ptr := lo.ToSlicePtr[string]([]string{"hello", "world"})
|
||||
// []*string{"hello", "world"}
|
||||
```
|
||||
|
||||
### ToAnySlice
|
||||
|
||||
Returns a slice with all elements mapped to `any` type.
|
||||
|
||||
```go
|
||||
elements := lo.ToAnySlice[int]([]int{1, 5, 1})
|
||||
// []any{1, 5, 1}
|
||||
```
|
||||
|
||||
### FromAnySlice
|
||||
|
||||
Returns an `any` slice with all elements mapped to a type. Returns false in case of type conversion failure.
|
||||
|
||||
```go
|
||||
elements, ok := lo.FromAnySlice[string]([]any{"foobar", 42})
|
||||
// []string{}, false
|
||||
|
||||
elements, ok := lo.FromAnySlice[string]([]any{"foobar", "42"})
|
||||
// []string{"foobar", "42"}, true
|
||||
```
|
||||
|
||||
### Empty
|
||||
|
||||
Returns an empty value.
|
||||
|
||||
6
find.go
6
find.go
@@ -216,11 +216,7 @@ func Sample[T any](collection []T) T {
|
||||
func Samples[T any](collection []T, count int) []T {
|
||||
size := len(collection)
|
||||
|
||||
// put values into a map, for faster deletion
|
||||
cOpy := make([]T, 0, size)
|
||||
for _, v := range collection {
|
||||
cOpy = append(cOpy, v)
|
||||
}
|
||||
cOpy := append([]T{}, collection...)
|
||||
|
||||
results := []T{}
|
||||
|
||||
|
||||
32
pointers.go
32
pointers.go
@@ -1,32 +0,0 @@
|
||||
package lo
|
||||
|
||||
// ToPtr returns a pointer copy of value.
|
||||
func ToPtr[T any](x T) *T {
|
||||
return &x
|
||||
}
|
||||
|
||||
// ToSlicePtr returns a slice of pointer copy of value.
|
||||
func ToSlicePtr[T any](collection []T) []*T {
|
||||
return Map(collection, func(x T, _ int) *T {
|
||||
return &x
|
||||
})
|
||||
}
|
||||
|
||||
// Empty returns an empty value.
|
||||
func Empty[T any]() T {
|
||||
var t T
|
||||
return t
|
||||
}
|
||||
|
||||
// Coalesce returns the first non-empty arguments. Arguments must be comparable.
|
||||
func Coalesce[T comparable](v ...T) (result T, ok bool) {
|
||||
for _, e := range v {
|
||||
if e != result {
|
||||
result = e
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
9
slice.go
9
slice.go
@@ -406,12 +406,3 @@ func Replace[T comparable](collection []T, old T, new T, n int) []T {
|
||||
func ReplaceAll[T comparable](collection []T, old T, new T) []T {
|
||||
return Replace[T](collection, old, new, -1)
|
||||
}
|
||||
|
||||
// ToAnySlice returns a slice with all elements mapped to any type
|
||||
func ToAnySlice[T any](collection []T) []any {
|
||||
result := make([]any, len(collection))
|
||||
for i, item := range collection {
|
||||
result[i] = item
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -455,15 +455,3 @@ func TestReplaceAll(t *testing.T) {
|
||||
is.Equal([]int{42, 1, 42, 1, 2, 3, 42}, out1)
|
||||
is.Equal([]int{0, 1, 0, 1, 2, 3, 0}, out2)
|
||||
}
|
||||
|
||||
func TestToAnySlice(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
in1 := []int{0, 1, 2, 3}
|
||||
in2 := []int{}
|
||||
out1 := ToAnySlice(in1)
|
||||
out2 := ToAnySlice(in2)
|
||||
|
||||
is.Equal([]any{0, 1, 2, 3}, out1)
|
||||
is.Equal([]any{}, out2)
|
||||
}
|
||||
|
||||
58
type_manipulation.go
Normal file
58
type_manipulation.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package lo
|
||||
|
||||
// ToPtr returns a pointer copy of value.
|
||||
func ToPtr[T any](x T) *T {
|
||||
return &x
|
||||
}
|
||||
|
||||
// ToSlicePtr returns a slice of pointer copy of value.
|
||||
func ToSlicePtr[T any](collection []T) []*T {
|
||||
return Map(collection, func(x T, _ int) *T {
|
||||
return &x
|
||||
})
|
||||
}
|
||||
|
||||
// ToAnySlice returns a slice with all elements mapped to `any` type
|
||||
func ToAnySlice[T any](collection []T) []any {
|
||||
result := make([]any, len(collection))
|
||||
for i, item := range collection {
|
||||
result[i] = item
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// FromAnySlice returns an `any` slice with all elements mapped to a type.
|
||||
// Returns false in case of type conversion failure.
|
||||
func FromAnySlice[T any](in []any) (out []T, ok bool) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
out = []T{}
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
result := make([]T, len(in))
|
||||
for i, item := range in {
|
||||
result[i] = item.(T)
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
|
||||
// Empty returns an empty value.
|
||||
func Empty[T any]() T {
|
||||
var t T
|
||||
return t
|
||||
}
|
||||
|
||||
// Coalesce returns the first non-empty arguments. Arguments must be comparable.
|
||||
func Coalesce[T comparable](v ...T) (result T, ok bool) {
|
||||
for _, e := range v {
|
||||
if e != result {
|
||||
result = e
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -24,6 +24,46 @@ func TestToSlicePtr(t *testing.T) {
|
||||
is.Equal(result1, []*string{&str1, &str2})
|
||||
}
|
||||
|
||||
func TestToAnySlice(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
in1 := []int{0, 1, 2, 3}
|
||||
in2 := []int{}
|
||||
out1 := ToAnySlice(in1)
|
||||
out2 := ToAnySlice(in2)
|
||||
|
||||
is.Equal([]any{0, 1, 2, 3}, out1)
|
||||
is.Equal([]any{}, out2)
|
||||
}
|
||||
|
||||
func TestFromAnySlice(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
is.NotPanics(func() {
|
||||
out1, ok1 := FromAnySlice[string]([]any{"foobar", 42})
|
||||
out2, ok2 := FromAnySlice[string]([]any{"foobar", "42"})
|
||||
|
||||
is.Equal([]string{}, out1)
|
||||
is.False(ok1)
|
||||
is.Equal([]string{"foobar", "42"}, out2)
|
||||
is.True(ok2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
//nolint:unused
|
||||
type test struct {
|
||||
foobar string
|
||||
}
|
||||
|
||||
is.Empty(Empty[string]())
|
||||
is.Empty(Empty[int64]())
|
||||
is.Empty(Empty[test]())
|
||||
is.Empty(Empty[chan string]())
|
||||
}
|
||||
|
||||
func TestCoalesce(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
Reference in New Issue
Block a user