feature: add Mode function with tests and documentation (#644)

* Update README.md

Fixed the error in the usage example of lo.Latest in readme.md

use []time.Time{…} (value of type []time.Time) as time.Time value in argument to lo.Latest

* Update README.md

* feature: add Mode function with tests and documentation

---------

Co-authored-by: Samuel Berthe <dev@samuel-berthe.fr>
This commit is contained in:
ghosx
2025-07-07 08:05:39 +08:00
committed by GitHub
parent c66dc5432a
commit bededfed30
3 changed files with 70 additions and 0 deletions

View File

@@ -158,6 +158,7 @@ Supported math helpers:
- [ProductBy](#productby)
- [Mean](#mean)
- [MeanBy](#meanby)
- [Mode](#mode)
Supported helpers for strings:
@@ -1645,6 +1646,30 @@ mean := lo.MeanBy([]float64{}, mapper)
// 0
```
### Mode
Calculates the mode(most frequent value) of a collection of numbers.
If multiple values have the same highest frequency, then multiple values are returned.
If the collection is empty, the zero value of `T[]` is returned.
```go
mode := lo.Mode([]int{2, 2, 3, 4})
// [2]
mode := lo.Mode([]float64{2, 2, 3, 3})
// [2, 3]
mode := lo.Mode([]float64{})
// []
mode := lo.Mode([]int{1, 2, 3, 4, 5, 6, 7, 8, 9})
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
```
### RandomString
Returns a random string of the specified length and made of the specified charset.

28
math.go
View File

@@ -140,3 +140,31 @@ func MeanBy[T any, R constraints.Float | constraints.Integer](collection []T, it
var sum = SumBy(collection, iteratee)
return sum / length
}
// Mode returns the mode (most frequent value) of a collection.
// If multiple values have the same highest frequency, then multiple values are returned.
// If the collection is empty, then the zero value of T is returned.
func Mode[T constraints.Integer | constraints.Float](collection []T) []T {
var length = T(len(collection))
if length == 0 {
return []T{}
}
var mode = make([]T, 0)
maxFreq := 0
frequency := make(map[T]int)
for _, item := range collection {
frequency[item]++
count := frequency[item]
if count > maxFreq {
maxFreq = count
mode = []T{item}
} else if count == maxFreq {
mode = append(mode, item)
}
}
return mode
}

View File

@@ -171,3 +171,20 @@ func TestMeanBy(t *testing.T) {
is.Equal(result3, uint32(3))
is.Equal(result4, uint32(0))
}
func TestMode(t *testing.T) {
t.Parallel()
is := assert.New(t)
result1 := Mode([]float32{2.3, 3.3, 3.3, 5.3})
result2 := Mode([]int32{2, 2, 3, 4})
result3 := Mode([]uint32{2, 2, 3, 3})
result4 := Mode([]uint32{})
result5 := Mode([]int{1, 2, 3, 4, 5, 6, 7, 8, 9})
is.Equal(result1, []float32{3.3})
is.Equal(result2, []int32{2})
is.Equal(result3, []uint32{2, 3})
is.Equal(result4, []uint32{})
is.Equal(result5, []int{1, 2, 3, 4, 5, 6, 7, 8, 9})
}