mirror of
https://github.com/samber/lo.git
synced 2026-04-22 23:47:11 +08:00
feat: add Product and ProductBy functions (#566)
Co-authored-by: John.Devitt@cdp.net <JohnDevitt@Mac.cust.communityfibre.co.uk>
This commit is contained in:
@@ -155,6 +155,8 @@ Supported math helpers:
|
||||
- [Clamp](#clamp)
|
||||
- [Sum](#sum)
|
||||
- [SumBy](#sumby)
|
||||
- [Product](#product)
|
||||
- [ProductBy](#productby)
|
||||
- [Mean](#mean)
|
||||
- [MeanBy](#meanby)
|
||||
|
||||
@@ -866,7 +868,6 @@ l := lo.DropByIndex([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1)
|
||||
|
||||
[[play](https://go.dev/play/p/JswS7vXRJP2)]
|
||||
|
||||
|
||||
### Reject
|
||||
|
||||
The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
|
||||
@@ -885,6 +886,7 @@ odd := lo.Reject([]int{1, 2, 3, 4}, func(x int, _ int) bool {
|
||||
The opposite of FilterMap, this method returns a slice which obtained after both filtering and mapping using the given callback function.
|
||||
|
||||
The callback function should return two values:
|
||||
|
||||
- the result of the mapping operation and
|
||||
- whether the result element should be included or not.
|
||||
|
||||
@@ -1511,7 +1513,35 @@ sum := lo.SumBy(strings, func(item string) int {
|
||||
// 6
|
||||
```
|
||||
|
||||
[[play](https://go.dev/play/p/Dz_a_7jN_ca)]
|
||||
### Product
|
||||
|
||||
Calculates the product of the values in a collection.
|
||||
|
||||
If collection is empty 0 is returned.
|
||||
|
||||
```go
|
||||
list := []int{1, 2, 3, 4, 5}
|
||||
product := lo.Product(list)
|
||||
// 120
|
||||
```
|
||||
|
||||
[[play](https://go.dev/play/p/2_kjM_smtAH)]
|
||||
|
||||
### ProductBy
|
||||
|
||||
Calculates the product of the values in a collection using the given return value from the iteration function.
|
||||
|
||||
If collection is empty 0 is returned.
|
||||
|
||||
```go
|
||||
strings := []string{"foo", "bar"}
|
||||
product := lo.ProductBy(strings, func(item string) int {
|
||||
return len(item)
|
||||
})
|
||||
// 9
|
||||
```
|
||||
|
||||
[[play](https://go.dev/play/p/wadzrWr9Aer)]
|
||||
|
||||
### Mean
|
||||
|
||||
@@ -2693,6 +2723,7 @@ first := lo.FirstOrEmpty([]int{1, 2, 3})
|
||||
first := lo.FirstOrEmpty([]int{})
|
||||
// 0
|
||||
```
|
||||
|
||||
### FirstOr
|
||||
|
||||
Returns the first element of a collection or the fallback value if empty.
|
||||
@@ -2730,6 +2761,7 @@ last := lo.LastOrEmpty([]int{1, 2, 3})
|
||||
last := lo.LastOrEmpty([]int{})
|
||||
// 0
|
||||
```
|
||||
|
||||
### LastOr
|
||||
|
||||
Returns the first element of a collection or the fallback value if empty.
|
||||
@@ -3644,7 +3676,6 @@ iterations, duration, ok := lo.WaitFor(laterTrue, 10*time.Millisecond, 5*time.Mi
|
||||
// false
|
||||
```
|
||||
|
||||
|
||||
### WaitForWithContext
|
||||
|
||||
Runs periodically until a condition is validated or context is invalid.
|
||||
|
||||
@@ -85,6 +85,44 @@ func SumBy[T any, R constraints.Float | constraints.Integer | constraints.Comple
|
||||
return sum
|
||||
}
|
||||
|
||||
// Product gets the product of the values in a collection. If collection is empty 0 is returned.
|
||||
// Play: https://go.dev/play/p/2_kjM_smtAH
|
||||
func Product[T constraints.Float | constraints.Integer | constraints.Complex](collection []T) T {
|
||||
|
||||
if collection == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if len(collection) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var product T = 1
|
||||
for i := range collection {
|
||||
product *= collection[i]
|
||||
}
|
||||
return product
|
||||
}
|
||||
|
||||
// ProductBy summarizes the values in a collection using the given return value from the iteration function. If collection is empty 0 is returned.
|
||||
// Play: https://go.dev/play/p/wadzrWr9Aer
|
||||
func ProductBy[T any, R constraints.Float | constraints.Integer | constraints.Complex](collection []T, iteratee func(item T) R) R {
|
||||
|
||||
if collection == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
if len(collection) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var product R = 1
|
||||
for i := range collection {
|
||||
product = product * iteratee(collection[i])
|
||||
}
|
||||
return product
|
||||
}
|
||||
|
||||
// Mean calculates the mean of a collection of numbers.
|
||||
func Mean[T constraints.Float | constraints.Integer](collection []T) T {
|
||||
var length = T(len(collection))
|
||||
|
||||
@@ -98,6 +98,46 @@ func TestSumBy(t *testing.T) {
|
||||
is.Equal(result5, complex128(6_6))
|
||||
}
|
||||
|
||||
func TestProduct(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := Product([]float32{2.3, 3.3, 4, 5.3})
|
||||
result2 := Product([]int32{2, 3, 4, 5})
|
||||
result3 := Product([]int32{7, 8, 9, 0})
|
||||
result4 := Product([]int32{7, -1, 9, 2})
|
||||
result5 := Product([]uint32{2, 3, 4, 5})
|
||||
result6 := Product([]uint32{})
|
||||
result7 := Product([]complex128{4_4, 2_2})
|
||||
|
||||
is.Equal(result1, float32(160.908))
|
||||
is.Equal(result2, int32(120))
|
||||
is.Equal(result3, int32(0))
|
||||
is.Equal(result4, int32(-126))
|
||||
is.Equal(result5, uint32(120))
|
||||
is.Equal(result6, uint32(0))
|
||||
is.Equal(result7, complex128(96_8))
|
||||
}
|
||||
|
||||
func TestProductBy(t *testing.T) {
|
||||
is := assert.New(t)
|
||||
|
||||
result1 := ProductBy([]float32{2.3, 3.3, 4, 5.3}, func(n float32) float32 { return n })
|
||||
result2 := ProductBy([]int32{2, 3, 4, 5}, func(n int32) int32 { return n })
|
||||
result3 := ProductBy([]int32{7, 8, 9, 0}, func(n int32) int32 { return n })
|
||||
result4 := ProductBy([]int32{7, -1, 9, 2}, func(n int32) int32 { return n })
|
||||
result5 := ProductBy([]uint32{2, 3, 4, 5}, func(n uint32) uint32 { return n })
|
||||
result6 := ProductBy([]uint32{}, func(n uint32) uint32 { return n })
|
||||
result7 := ProductBy([]complex128{4_4, 2_2}, func(n complex128) complex128 { return n })
|
||||
|
||||
is.Equal(result1, float32(160.908))
|
||||
is.Equal(result2, int32(120))
|
||||
is.Equal(result3, int32(0))
|
||||
is.Equal(result4, int32(-126))
|
||||
is.Equal(result5, uint32(120))
|
||||
is.Equal(result6, uint32(0))
|
||||
is.Equal(result7, complex128(96_8))
|
||||
}
|
||||
|
||||
func TestMean(t *testing.T) {
|
||||
t.Parallel()
|
||||
is := assert.New(t)
|
||||
|
||||
Reference in New Issue
Block a user