Skip to content

Commit

Permalink
Merge branch 'master' into snyk-fix-9970e4edc90c324795f67976f79e0ce5
Browse files Browse the repository at this point in the history
  • Loading branch information
samber authored Jul 15, 2024
2 parents 3ec051a + 9e34397 commit 5201009
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

FROM golang:1.21.11
FROM golang:1.21.12

WORKDIR /go/src/github.com/samber/lo

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,11 @@ Supported search helpers:
- [Min](#min)
- [MinBy](#minby)
- [Earliest](#earliest)
- [EarliestBy](#earliestby)
- [Max](#max)
- [MaxBy](#maxby)
- [Latest](#latest)
- [LatestBy](#latestby)
- [First](#first)
- [FirstOrEmpty](#FirstOrEmpty)
- [FirstOr](#FirstOr)
Expand Down Expand Up @@ -2260,6 +2262,23 @@ earliest := lo.Earliest(time.Now(), time.Time{})
// 0001-01-01 00:00:00 +0000 UTC
```

### EarliestBy

Search the minimum time.Time of a collection using the given iteratee function.

Returns zero value when the collection is empty.

```go
type foo struct {
bar time.Time
}

earliest := lo.EarliestBy([]foo{{time.Now()}, {}}, func(i foo) time.Time {
return i.bar
})
// {bar:{2023-04-01 01:02:03 +0000 UTC}}
```

### Max

Search the maximum value of a collection.
Expand Down Expand Up @@ -2308,6 +2327,23 @@ latest := lo.Latest([]time.Time{time.Now(), time.Time{}})
// 2023-04-01 01:02:03 +0000 UTC
```

### LatestBy

Search the maximum time.Time of a collection using the given iteratee function.

Returns zero value when the collection is empty.

```go
type foo struct {
bar time.Time
}

latest := lo.LatestBy([]foo{{time.Now()}, {}}, func(i foo) time.Time {
return i.bar
})
// {bar:{2023-04-01 01:02:03 +0000 UTC}}
```

### First

Returns the first element of a collection and check for availability of the first element.
Expand Down
48 changes: 48 additions & 0 deletions find.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,30 @@ func Earliest(times ...time.Time) time.Time {
return min
}

// EarliestBy search the minimum time.Time of a collection using the given iteratee function.
// Returns zero value when the collection is empty.
func EarliestBy[T any](collection []T, iteratee func(item T) time.Time) T {
var earliest T

if len(collection) == 0 {
return earliest
}

earliest = collection[0]
earliestTime := iteratee(collection[0])

for i := 1; i < len(collection); i++ {
itemTime := iteratee(collection[i])

if itemTime.Before(earliestTime) {
earliest = collection[i]
earliestTime = itemTime
}
}

return earliest
}

// Max searches the maximum value of a collection.
// Returns zero value when the collection is empty.
func Max[T constraints.Ordered](collection []T) T {
Expand Down Expand Up @@ -353,6 +377,30 @@ func Latest(times ...time.Time) time.Time {
return max
}

// LatestBy search the maximum time.Time of a collection using the given iteratee function.
// Returns zero value when the collection is empty.
func LatestBy[T any](collection []T, iteratee func(item T) time.Time) T {
var latest T

if len(collection) == 0 {
return latest
}

latest = collection[0]
latestTime := iteratee(collection[0])

for i := 1; i < len(collection); i++ {
itemTime := iteratee(collection[i])

if itemTime.After(latestTime) {
latest = collection[i]
latestTime = itemTime
}
}

return latest
}

// First returns the first element of a collection and check for availability of the first element.
func First[T any](collection []T) (T, bool) {
length := len(collection)
Expand Down
52 changes: 52 additions & 0 deletions find_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,32 @@ func TestEarliest(t *testing.T) {
is.Equal(result2, time.Time{})
}

func TestEarliestBy(t *testing.T) {
t.Parallel()
is := assert.New(t)

type foo struct {
bar time.Time
}

t1 := time.Now()
t2 := t1.Add(time.Hour)
t3 := t1.Add(-time.Hour)
result1 := EarliestBy([]foo{{t1}, {t2}, {t3}}, func(i foo) time.Time {
return i.bar
})
result2 := EarliestBy([]foo{{t1}}, func(i foo) time.Time {
return i.bar
})
result3 := EarliestBy([]foo{}, func(i foo) time.Time {
return i.bar
})

is.Equal(result1, foo{t3})
is.Equal(result2, foo{t1})
is.Equal(result3, foo{})
}

func TestMax(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down Expand Up @@ -383,6 +409,32 @@ func TestLatest(t *testing.T) {
is.Equal(result2, time.Time{})
}

func TestLatestBy(t *testing.T) {
t.Parallel()
is := assert.New(t)

type foo struct {
bar time.Time
}

t1 := time.Now()
t2 := t1.Add(time.Hour)
t3 := t1.Add(-time.Hour)
result1 := LatestBy([]foo{{t1}, {t2}, {t3}}, func(i foo) time.Time {
return i.bar
})
result2 := LatestBy([]foo{{t1}}, func(i foo) time.Time {
return i.bar
})
result3 := LatestBy([]foo{}, func(i foo) time.Time {
return i.bar
})

is.Equal(result1, foo{t2})
is.Equal(result2, foo{t1})
is.Equal(result3, foo{})
}

func TestFirst(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down
2 changes: 1 addition & 1 deletion slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func Chunk[T any, Slice ~[]T](collection Slice, size int) []Slice {
if last > len(collection) {
last = len(collection)
}
result = append(result, collection[i*size:last])
result = append(result, collection[i*size:last:last])
}

return result
Expand Down
6 changes: 6 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ func TestChunk(t *testing.T) {
allStrings := myStrings{"", "foo", "bar"}
nonempty := Chunk(allStrings, 2)
is.IsType(nonempty[0], allStrings, "type preserved")

// appending to a chunk should not affect original array
originalArray := []int{0, 1, 2, 3, 4, 5}
result5 := Chunk(originalArray, 2)
result5[0] = append(result5[0], 6)
is.Equal(originalArray, []int{0, 1, 2, 3, 4, 5})
}

func TestPartitionBy(t *testing.T) {
Expand Down

0 comments on commit 5201009

Please sign in to comment.