Skip to content

Commit

Permalink
feat: adding LastOrEmpty and LastOr (#474)
Browse files Browse the repository at this point in the history
  • Loading branch information
samber authored Jun 27, 2024
1 parent a94098f commit 5aa64ef
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 35 deletions.
50 changes: 41 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,12 @@ Supported search helpers:
- [Max](#max)
- [MaxBy](#maxby)
- [Latest](#latest)
- [Last](#last)
- [First](#first)
- [FirstOrEmpty](#FirstOrEmpty)
- [FirstOr](#FirstOr)
- [Last](#last)
- [LastOrEmpty](#LastOrEmpty)
- [LastOr](#LastOr)
- [Nth](#nth)
- [Sample](#sample)
- [Samples](#samples)
Expand Down Expand Up @@ -2238,14 +2240,6 @@ 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.

```go
last, err := lo.Last([]int{1, 2, 3})
// 3
```
### First

Returns the first element of a collection and check for availability of the first element.
Expand All @@ -2257,6 +2251,7 @@ first, ok := lo.First([]int{1, 2, 3})
first, ok := lo.First([]int{})
// 0, false
```

### FirstOrEmpty

Returns the first element of a collection or zero value if empty.
Expand All @@ -2280,6 +2275,43 @@ first := lo.FirstOr([]int{}, 31)
// 31
```

### Last

Returns the last element of a collection or error if empty.

```go
last, ok := lo.Last([]int{1, 2, 3})
// 3
// true

last, ok := lo.Last([]int{})
// 0
// false
```

### FirstOrEmpty

Returns the first element of a collection or zero value if empty.

```go
last := lo.LastOrEmpty([]int{1, 2, 3})
// 3

last := lo.LastOrEmpty([]int{})
// 0
```
### FirstOr

Returns the first element of a collection or the fallback value if empty.

```go
last := lo.LastOr([]int{1, 2, 3}, 245)
// 3

last := lo.LastOr([]int{}, 31)
// 31
```

### Nth

Returns the element at index `nth` of collection. If `nth` is negative, the nth element from the end is returned. An error is returned when nth is out of slice bounds.
Expand Down
42 changes: 29 additions & 13 deletions find.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,39 +355,55 @@ func Latest(times ...time.Time) time.Time {
return max
}

// Last returns the last element of a collection or error if empty.
func Last[T any](collection []T) (T, error) {
// 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)

if length == 0 {
var t T
return t, fmt.Errorf("last: cannot extract the last element of an empty slice")
return t, false
}

return collection[length-1], nil
return collection[0], true
}

// Returns the first element of a collection and check for availability of the first element.
func First[T any](collection []T) (T, bool) {
// FirstOrEmpty returns the first element of a collection or zero value if empty.
func FirstOrEmpty[T any](collection []T) T {
i, _ := First(collection)
return i
}

// FirstOr returns the first element of a collection or the fallback value if empty.
func FirstOr[T any](collection []T, fallback T) T {
i, ok := First(collection)
if !ok {
return fallback
}

return i
}

// Last returns the last element of a collection or error if empty.
func Last[T any](collection []T) (T, bool) {
length := len(collection)

if length == 0 {
var t T
return t, false
}

return collection[0], true
return collection[length-1], true
}

// Returns the first element of a collection or zero value if empty.
func FirstOrEmpty[T any](collection []T) T {
i, _ := First(collection)
// Returns the last element of a collection or zero value if empty.
func LastOrEmpty[T any](collection []T) T {
i, _ := Last(collection)
return i
}

// Returns the first element of a collection or the fallback value if empty.
func FirstOr[T any](collection []T, fallback T) T {
i, ok := First(collection)
// LastOr returns the last element of a collection or the fallback value if empty.
func LastOr[T any](collection []T, fallback T) T {
i, ok := Last(collection)
if !ok {
return fallback
}
Expand Down
52 changes: 39 additions & 13 deletions find_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,19 +359,6 @@ func TestLatest(t *testing.T) {
is.Equal(result2, time.Time{})
}

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

result1, err1 := Last([]int{1, 2, 3})
result2, err2 := Last([]int{})

is.Equal(result1, 3)
is.Equal(err1, nil)
is.Equal(result2, 0)
is.Equal(err2, fmt.Errorf("last: cannot extract the last element of an empty slice"))
}

func TestFirst(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down Expand Up @@ -411,6 +398,45 @@ func TestFirstOr(t *testing.T) {
is.Equal(result3, "test")
}

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

result1, ok1 := Last([]int{1, 2, 3})
result2, ok2 := Last([]int{})

is.Equal(result1, 3)
is.True(ok1)
is.Equal(result2, 0)
is.False(ok2)
}

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

result1 := LastOrEmpty([]int{1, 2, 3})
result2 := LastOrEmpty([]int{})
result3 := LastOrEmpty([]string{})

is.Equal(result1, 3)
is.Equal(result2, 0)
is.Equal(result3, "")
}

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

result1 := LastOr([]int{1, 2, 3}, 63)
result2 := LastOr([]int{}, 23)
result3 := LastOr([]string{}, "test")

is.Equal(result1, 3)
is.Equal(result2, 23)
is.Equal(result3, "test")
}

func TestNth(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down

0 comments on commit 5aa64ef

Please sign in to comment.