diff --git a/README.md b/README.md index 044bf3bb..9d37ed23 100644 --- a/README.md +++ b/README.md @@ -209,8 +209,10 @@ Supported search helpers: - [FindDuplicatesBy](#findduplicatesby) - [Min](#min) - [MinBy](#minby) +- [Earliest](#earliest) - [Max](#max) - [MaxBy](#maxby) +- [Latest](#latest) - [Last](#last) - [Nth](#nth) - [Sample](#sample) @@ -2066,7 +2068,7 @@ duplicatedValues := lo.FindDuplicatesBy([]int{3, 4, 5, 6, 7}, func(i int) int { Search the minimum value of a collection. -Returns zero value when collection is empty. +Returns zero value when the collection is empty. ```go min := lo.Min([]int{1, 2, 3}) @@ -2085,7 +2087,7 @@ Search the minimum value of a collection using the given comparison function. If several values of the collection are equal to the smallest value, returns the first such value. -Returns zero value when collection is empty. +Returns zero value when the collection is empty. ```go min := lo.MinBy([]string{"s1", "string2", "s3"}, func(item string, min string) bool { @@ -2099,11 +2101,22 @@ min := lo.MinBy([]string{}, func(item string, min string) bool { // "" ``` +### Earliest + +Search the minimum time.Time of a collection. + +Returns zero value when the collection is empty. + +```go +earliest := lo.Earliest(time.Now(), time.Time{}) +// 0001-01-01 00:00:00 +0000 UTC +``` + ### Max Search the maximum value of a collection. -Returns zero value when collection is empty. +Returns zero value when the collection is empty. ```go max := lo.Max([]int{1, 2, 3}) @@ -2122,7 +2135,7 @@ Search the maximum value of a collection using the given comparison function. If several values of the collection are equal to the greatest value, returns the first such value. -Returns zero value when collection is empty. +Returns zero value when the collection is empty. ```go max := lo.MaxBy([]string{"string1", "s2", "string3"}, func(item string, max string) bool { @@ -2136,6 +2149,17 @@ max := lo.MaxBy([]string{}, func(item string, max string) bool { // "" ``` +### Latest + +Search the maximum time.Time of a collection. + +Returns zero value when the collection is empty. + +```go +latest := lo.Latest([]time.Time{time.Now(), time.Time{}}) +// 2023-04-01 01:02:03 +0000 UTC +``` + ### Last Returns the last element of a collection or error if empty. diff --git a/find.go b/find.go index f8caeb89..503bfc89 100644 --- a/find.go +++ b/find.go @@ -3,6 +3,7 @@ package lo import ( "fmt" "math/rand" + "time" "golang.org/x/exp/constraints" ) @@ -221,7 +222,7 @@ func FindDuplicatesBy[T any, U comparable](collection []T, iteratee func(item T) } // Min search the minimum value of a collection. -// Returns zero value when collection is empty. +// Returns zero value when the collection is empty. func Min[T constraints.Ordered](collection []T) T { var min T @@ -244,7 +245,7 @@ func Min[T constraints.Ordered](collection []T) T { // MinBy search the minimum value of a collection using the given comparison function. // If several values of the collection are equal to the smallest value, returns the first such value. -// Returns zero value when collection is empty. +// Returns zero value when the collection is empty. func MinBy[T any](collection []T, comparison func(a T, b T) bool) T { var min T @@ -265,8 +266,30 @@ func MinBy[T any](collection []T, comparison func(a T, b T) bool) T { return min } +// Earliest search the minimum time.Time of a collection. +// Returns zero value when the collection is empty. +func Earliest(times ...time.Time) time.Time { + var min time.Time + + if len(times) == 0 { + return min + } + + min = times[0] + + for i := 1; i < len(times); i++ { + item := times[i] + + if item.Before(min) { + min = item + } + } + + return min +} + // Max searches the maximum value of a collection. -// Returns zero value when collection is empty. +// Returns zero value when the collection is empty. func Max[T constraints.Ordered](collection []T) T { var max T @@ -289,7 +312,7 @@ func Max[T constraints.Ordered](collection []T) T { // MaxBy search the maximum value of a collection using the given comparison function. // If several values of the collection are equal to the greatest value, returns the first such value. -// Returns zero value when collection is empty. +// Returns zero value when the collection is empty. func MaxBy[T any](collection []T, comparison func(a T, b T) bool) T { var max T @@ -310,6 +333,28 @@ func MaxBy[T any](collection []T, comparison func(a T, b T) bool) T { return max } +// Latest search the maximum time.Time of a collection. +// Returns zero value when the collection is empty. +func Latest(times ...time.Time) time.Time { + var max time.Time + + if len(times) == 0 { + return max + } + + max = times[0] + + for i := 1; i < len(times); i++ { + item := times[i] + + if item.After(max) { + max = item + } + } + + return max +} + // Last returns the last element of a collection or error if empty. func Last[T any](collection []T) (T, error) { length := len(collection) diff --git a/find_test.go b/find_test.go index f4f8aaea..04446fb7 100644 --- a/find_test.go +++ b/find_test.go @@ -299,6 +299,19 @@ func TestMinBy(t *testing.T) { is.Equal(result3, "") } +func TestEarliest(t *testing.T) { + t.Parallel() + is := assert.New(t) + + a := time.Now() + b := a.Add(time.Hour) + result1 := Earliest(a, b) + result2 := Earliest() + + is.Equal(result1, a) + is.Equal(result2, time.Time{}) +} + func TestMax(t *testing.T) { t.Parallel() is := assert.New(t) @@ -333,6 +346,19 @@ func TestMaxBy(t *testing.T) { is.Equal(result3, "") } +func TestLatest(t *testing.T) { + t.Parallel() + is := assert.New(t) + + a := time.Now() + b := a.Add(time.Hour) + result1 := Latest(a, b) + result2 := Latest() + + is.Equal(result1, b) + is.Equal(result2, time.Time{}) +} + func TestLast(t *testing.T) { t.Parallel() is := assert.New(t)