Skip to content

Commit

Permalink
Merge pull request #31 from jsrdxzw/master
Browse files Browse the repository at this point in the history
Add Range
  • Loading branch information
samber committed Mar 10, 2022
2 parents 40e92cd + f30ae97 commit f1e3c4a
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ Other functional programming helpers:
- ToPtr
- ToSlicePtr
- Attempt
- Range / RangeFrom / RangeWithSteps

Constraints:

Expand Down Expand Up @@ -847,6 +848,34 @@ iter, err := lo.Attempt(0, func(i int) error {
// nil
```

### Range / RangeFrom / RangeWithSteps
Creates an array of numbers (positive and/or negative) progressing from start up to, but not including end.
```go
result := Range(4)
// [0, 1, 2, 3]

result := Range(-4);
// [0, -1, -2, -3]

result := RangeFrom(1, 5);
// [1, 2, 3, 4]

result := RangeFrom[float64](1.0, 5);
// [1.0, 2.0, 3.0, 4.0]

result := RangeWithSteps(0, 20, 5);
// [0, 5, 10, 15]

result := RangeWithSteps[float32](-1.0, -4.0, -1.0);
// [-1.0, -2.0, -3.0]

result := RangeWithSteps(1, 4, -1);
// []

result := Range(0);
// []
```

For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).

## 馃洨 Benchmark
Expand Down
50 changes: 50 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package lo

import "golang.org/x/exp/constraints"

// Range creates an array of numbers (positive and/or negative) with given length.
func Range(elementNum int) []int {
length := If(elementNum < 0, -elementNum).Else(elementNum)
result := make([]int, length)
step := If(elementNum < 0, -1).Else(1)
for i, j := 0, 0; i < length; i, j = i+1, j+step {
result[i] = j
}
return result
}

// RangeFrom creates an array of numbers from start with specified length.
func RangeFrom[T constraints.Integer | constraints.Float](start T, elementNum int) []T {
length := If(elementNum < 0, -elementNum).Else(elementNum)
result := make([]T, length)
step := If(elementNum < 0, -1).Else(1)
for i, j := 0, start; i < length; i, j = i+1, j+T(step) {
result[i] = j
}
return result
}

// RangeWithSteps creates an array of numbers (positive and/or negative) progressing from start up to, but not including end.
// step set to zero will return empty array.
func RangeWithSteps[T constraints.Integer | constraints.Float](start, end, step T) []T {
result := []T{}
if start == end || step == 0 {
return result
}
if start < end {
if step < 0 {
return result
}
for i := start; i < end; i += step {
result = append(result, i)
}
return result
}
if step > 0 {
return result
}
for i := start; i > end; i += step {
result = append(result, i)
}
return result
}
44 changes: 44 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package lo

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestRange(t *testing.T) {
is := assert.New(t)
result1 := Range(4)
result2 := Range(-4)
result3 := Range(0)
is.Equal(result1, []int{0, 1, 2, 3})
is.Equal(result2, []int{0, -1, -2, -3})
is.Equal(result3, []int{})
}

func TestRangeFrom(t *testing.T) {
is := assert.New(t)
result1 := RangeFrom(1, 5)
result2 := RangeFrom(-1, -5)
result3 := RangeFrom(10, 0)
result4 := RangeFrom[float64](2.0, 3)
result5 := RangeFrom[float64](-2.0, -3)
is.Equal(result1, []int{1, 2, 3, 4, 5})
is.Equal(result2, []int{-1, -2, -3, -4, -5})
is.Equal(result3, []int{})
is.Equal(result4, []float64{2.0, 3.0, 4.0})
is.Equal(result5, []float64{-2.0, -3.0, -4.0})
}

func TestRangeClose(t *testing.T) {
is := assert.New(t)
result1 := RangeWithSteps(0, 20, 6)
result2 := RangeWithSteps(0, 3, -5)
result3 := RangeWithSteps(1, 1, 0)
result4 := RangeWithSteps[float64](1.0, 4.0, 2.0)
result5 := RangeWithSteps[float32](-1.0, -4.0, -1.0)
is.Equal(result1, []int{0, 6, 12, 18})
is.Equal(result2, []int{})
is.Equal(result3, []int{})
is.Equal(result4, []float64{1.0, 3.0})
is.Equal(result5, []float32{-1.0, -2.0, -3.0})
}

0 comments on commit f1e3c4a

Please sign in to comment.