Repository: samber/lo
File: find.go (Go)

Code before:
func LastOr[T any](collection []T, fallback T) T {
	i, ok := Last(collection)
	if !ok {
		return fallback
	}

	return i
}

// 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.
func Nth[T any, N constraints.Integer](collection []T, nth N) (T, error) {
	n := int(nth)
	l := len(collection)
	if n >= l || -n > l {
		var t T
		return t, fmt.Errorf("nth: %d out of slice bounds", n)
	}

	if n >= 0 {
		return collection[n], nil
	}
	return collection[l+n], nil
}

// randomIntGenerator is a function that should return a random integer in the range [0, n-1]
// where n is the parameter passed to the randomIntGenerator.
type randomIntGenerator func(int) int

// Sample returns a random item from collection.
func Sample[T any](collection []T) T {
	result := SampleBy(collection, rand.IntN)
	return result
}

// SampleBy returns a random item from collection, using randomIntGenerator as the random index generator.
func SampleBy[T any](collection []T, randomIntGenerator randomIntGenerator) T {
	size := len(collection)
	if size == 0 {
		return Empty[T]()
	}
	return collection[randomIntGenerator(size)]
}

// Samples returns N random unique items from collection.
func Samples[T any, Slice ~[]T](collection Slice, count int) Slice {
	results := SamplesBy(collection, count, rand.IntN)
	return results
}

// SamplesBy returns N random unique items from collection, using randomIntGenerator as the random index generator.

Review comment (suggestion):
```suggestion
// randomIntGenerator is a function that should return a random integer in the range [0, n)
```

this is the right math notation

Code after:
func LastOr[T any](collection []T, fallback T) T {
	i, ok := Last(collection)
	if !ok {
		return fallback
	}

	return i
}

// 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.
func Nth[T any, N constraints.Integer](collection []T, nth N) (T, error) {
	n := int(nth)
	l := len(collection)
	if n >= l || -n > l {
		var t T
		return t, fmt.Errorf("nth: %d out of slice bounds", n)
	}

	if n >= 0 {
		return collection[n], nil
	}
	return collection[l+n], nil
}

// randomIntGenerator is a function that should return a random integer in the range [0, n)
// where n is the parameter passed to the randomIntGenerator.
type randomIntGenerator func(n int) int

// Sample returns a random item from collection.
func Sample[T any](collection []T) T {
	result := SampleBy(collection, rand.IntN)
	return result
}

// SampleBy returns a random item from collection, using randomIntGenerator as the random index generator.
func SampleBy[T any](collection []T, randomIntGenerator randomIntGenerator) T {
	size := len(collection)
	if size == 0 {
		return Empty[T]()
	}
	return collection[randomIntGenerator(size)]
}

// Samples returns N random unique items from collection.
func Samples[T any, Slice ~[]T](collection Slice, count int) Slice {
	results := SamplesBy(collection, count, rand.IntN)
	return results
}

// SamplesBy returns N random unique items from collection, using randomIntGenerator as the random index generator.