Skip to content

Commit 8a5ff48

Browse files
feat: add Product and ProductBy functions
1 parent efef0ff commit 8a5ff48

File tree

3 files changed

+113
-4
lines changed

3 files changed

+113
-4
lines changed

README.md

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ Supported math helpers:
151151
- [Clamp](#clamp)
152152
- [Sum](#sum)
153153
- [SumBy](#sumby)
154+
- [Product](#product)
155+
- [ProductBy](#productby)
154156
- [Mean](#mean)
155157
- [MeanBy](#meanby)
156158

@@ -787,7 +789,6 @@ l := lo.DropByIndex([]int{0, 1, 2, 3, 4, 5}, 2, 4, -1)
787789

788790
[[play](https://go.dev/play/p/JswS7vXRJP2)]
789791

790-
791792
### Reject
792793

793794
The opposite of Filter, this method returns the elements of collection that predicate does not return truthy for.
@@ -806,6 +807,7 @@ odd := lo.Reject([]int{1, 2, 3, 4}, func(x int, _ int) bool {
806807
The opposite of FilterMap, this method returns a slice which obtained after both filtering and mapping using the given callback function.
807808

808809
The callback function should return two values:
810+
809811
- the result of the mapping operation and
810812
- whether the result element should be included or not.
811813

@@ -1062,7 +1064,7 @@ keys := lo.Keys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"bar": 3})
10621064

10631065
### UniqKeys
10641066

1065-
Creates an array of unique map keys.
1067+
Creates an array of unique map keys.
10661068

10671069
```go
10681070
keys := lo.UniqKeys(map[string]int{"foo": 1, "bar": 2}, map[string]int{"baz": 3})
@@ -1411,7 +1413,35 @@ sum := lo.SumBy(strings, func(item string) int {
14111413
// 6
14121414
```
14131415

1414-
[[play](https://go.dev/play/p/Dz_a_7jN_ca)]
1416+
### Product
1417+
1418+
Calculates the product of the values in a collection.
1419+
1420+
If collection is empty 0 is returned.
1421+
1422+
```go
1423+
list := []int{1, 2, 3, 4, 5}
1424+
sum := lo.Product(list)
1425+
// 120
1426+
```
1427+
1428+
[[play](https://go.dev/play/p/2_kjM_smtAH)]
1429+
1430+
### ProductBy
1431+
1432+
Calculates the product of the values in a collection using the given return value from the iteration function.
1433+
1434+
If collection is empty 0 is returned.
1435+
1436+
```go
1437+
strings := []string{"foo", "bar"}
1438+
sum := lo.ProductBy(strings, func(item string) int {
1439+
return len(item)
1440+
})
1441+
// 9
1442+
```
1443+
1444+
[[play](https://go.dev/play/p/wadzrWr9Aer)]
14151445

14161446
### Mean
14171447

@@ -2421,6 +2451,7 @@ first := lo.FirstOrEmpty([]int{1, 2, 3})
24212451
first := lo.FirstOrEmpty([]int{})
24222452
// 0
24232453
```
2454+
24242455
### FirstOr
24252456

24262457
Returns the first element of a collection or the fallback value if empty.
@@ -2458,6 +2489,7 @@ last := lo.LastOrEmpty([]int{1, 2, 3})
24582489
last := lo.LastOrEmpty([]int{})
24592490
// 0
24602491
```
2492+
24612493
### LastOr
24622494

24632495
Returns the first element of a collection or the fallback value if empty.
@@ -3213,7 +3245,6 @@ iterations, duration, ok := lo.WaitFor(laterTrue, 10*time.Millisecond, 5*time.Mi
32133245
// false
32143246
```
32153247

3216-
32173248
### WaitForWithContext
32183249

32193250
Runs periodically until a condition is validated or context is invalid.

math.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,44 @@ func SumBy[T any, R constraints.Float | constraints.Integer | constraints.Comple
8585
return sum
8686
}
8787

88+
// Product gets the product of the values in a collection. If collection is empty 0 is returned.
89+
// Play: https://go.dev/play/p/2_kjM_smtAH
90+
func Product[T constraints.Float | constraints.Integer | constraints.Complex](collection []T) T {
91+
92+
if collection == nil {
93+
return 0
94+
}
95+
96+
if len(collection) == 0 {
97+
return 0
98+
}
99+
100+
var product T = 1
101+
for i := range collection {
102+
product *= collection[i]
103+
}
104+
return product
105+
}
106+
107+
// ProductBy summarizes the values in a collection using the given return value from the iteration function. If collection is empty 0 is returned.
108+
// Play: https://go.dev/play/p/wadzrWr9Aer
109+
func ProductBy[T any, R constraints.Float | constraints.Integer | constraints.Complex](collection []T, iteratee func(item T) R) R {
110+
111+
if collection == nil {
112+
return 0
113+
}
114+
115+
if len(collection) == 0 {
116+
return 0
117+
}
118+
119+
var product R = 1
120+
for i := range collection {
121+
product = product * iteratee(collection[i])
122+
}
123+
return product
124+
}
125+
88126
// Mean calculates the mean of a collection of numbers.
89127
func Mean[T constraints.Float | constraints.Integer](collection []T) T {
90128
var length = T(len(collection))

math_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,46 @@ func TestSumBy(t *testing.T) {
9898
is.Equal(result5, complex128(6_6))
9999
}
100100

101+
func TestProduct(t *testing.T) {
102+
is := assert.New(t)
103+
104+
result1 := Product([]float32{2.3, 3.3, 4, 5.3})
105+
result2 := Product([]int32{2, 3, 4, 5})
106+
result3 := Product([]int32{7, 8, 9, 0})
107+
result4 := Product([]int32{7, -1, 9, 2})
108+
result5 := Product([]uint32{2, 3, 4, 5})
109+
result6 := Product([]uint32{})
110+
result7 := Product([]complex128{4_4, 2_2})
111+
112+
is.Equal(result1, float32(160.908))
113+
is.Equal(result2, int32(120))
114+
is.Equal(result3, int32(0))
115+
is.Equal(result4, int32(-126))
116+
is.Equal(result5, uint32(120))
117+
is.Equal(result6, uint32(0))
118+
is.Equal(result7, complex128(96_8))
119+
}
120+
121+
func TestProductBy(t *testing.T) {
122+
is := assert.New(t)
123+
124+
result1 := ProductBy([]float32{2.3, 3.3, 4, 5.3}, func(n float32) float32 { return n })
125+
result2 := ProductBy([]int32{2, 3, 4, 5}, func(n int32) int32 { return n })
126+
result3 := ProductBy([]int32{7, 8, 9, 0}, func(n int32) int32 { return n })
127+
result4 := ProductBy([]int32{7, -1, 9, 2}, func(n int32) int32 { return n })
128+
result5 := ProductBy([]uint32{2, 3, 4, 5}, func(n uint32) uint32 { return n })
129+
result6 := ProductBy([]uint32{}, func(n uint32) uint32 { return n })
130+
result7 := ProductBy([]complex128{4_4, 2_2}, func(n complex128) complex128 { return n })
131+
132+
is.Equal(result1, float32(160.908))
133+
is.Equal(result2, int32(120))
134+
is.Equal(result3, int32(0))
135+
is.Equal(result4, int32(-126))
136+
is.Equal(result5, uint32(120))
137+
is.Equal(result6, uint32(0))
138+
is.Equal(result7, complex128(96_8))
139+
}
140+
101141
func TestMean(t *testing.T) {
102142
t.Parallel()
103143
is := assert.New(t)

0 commit comments

Comments
 (0)