Skip to content

Commit

Permalink
Added Rotate (#198)
Browse files Browse the repository at this point in the history
Rotate returns slice circularly rotated by a number of positions n.
If n is positive, the slice is rotated right.
If n is negative, the slice is rotated left.
  • Loading branch information
SlothNinja authored Sep 8, 2023
1 parent f1ace5f commit 4912a95
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 2 deletions.
7 changes: 7 additions & 0 deletions v2/of.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ func (o OfSlice[T]) Reverse() OfSlice[T] {
return OfSlice[T]{Reverse(o.Result)}
}

// Rotate returns slice circularly rotated by a number of positions n.
// If n is positive, the slice is rotated right.
// If n is negative, the slice is rotated left.
func (o OfSlice[T]) Rotate(n int) OfSlice[T] {
return OfSlice[T]{Rotate(o.Result, n)}
}

// Send sends elements to channel
// in normal act it sends all elements but if func canceled it can be less
//
Expand Down
13 changes: 11 additions & 2 deletions v2/of_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package pie_test

import (
"github.com/elliotchance/pie/v2"
"github.com/stretchr/testify/assert"
"strings"
"testing"

"github.com/elliotchance/pie/v2"
"github.com/stretchr/testify/assert"
)

func TestOf(t *testing.T) {
Expand Down Expand Up @@ -36,4 +37,12 @@ func TestOf(t *testing.T) {

assert.Equal(t, []string{"Bob", "Sally"}, names)
})

t.Run("rotate", func(t *testing.T) {
names := pie.Of([]string{"Bob", "Sally", "John", "Jane"}).
Rotate(1).
Result

assert.Equal(t, []string{"Jane", "Bob", "Sally", "John"}, names)
})
}
30 changes: 30 additions & 0 deletions v2/rotate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pie

// Rotate return slice circularly rotated by a number of positions n.
// If n is positive, the slice is rotated right.
// If n is negative, the slice is rotated left.
func Rotate[T any](ss []T, n int) []T {

length := len(ss)

// Avoid the allocation.
// If there is one element or less, then already rotated.
if length < 2 {
return ss
}

// Normalize shift
// no div by 0 since length >= 2
shift := -n % length
if shift < 0 {
shift = length + shift
}

// Avoid the allocation.
// If normalized shift is 0, then already rotated.
if shift == 0 {
return ss
}

return append(DropTop(ss, shift), Top(ss, shift)...)
}
89 changes: 89 additions & 0 deletions v2/rotate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package pie_test

import (
"testing"

"github.com/elliotchance/pie/v2"
"github.com/stretchr/testify/assert"
)

var rotateTests = []struct {
ss []float64
rotated []float64
n int
}{
{
nil,
nil,
0,
},
{
[]float64{1.23, 2.34},
[]float64{1.23, 2.34},
0,
},
{
[]float64{},
[]float64{},
0,
},
{
[]float64{},
[]float64{},
3,
},
{
[]float64{1.23, 2.34},
[]float64{2.34, 1.23},
1,
},
{
[]float64{1.23, 2.34},
[]float64{2.34, 1.23},
-1,
},
{
[]float64{1.23},
[]float64{1.23},
1000,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{1.23, 2.34, 3.45},
3,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{1.23, 2.34, 3.45},
-3,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{1.23, 2.34, 3.45},
6,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{1.23, 2.34, 3.45},
-6,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{2.34, 3.45, 1.23},
-1,
},
{
[]float64{1.23, 2.34, 3.45},
[]float64{3.45, 1.23, 2.34},
1,
},
}

func TestRotate(t *testing.T) {
for _, test := range rotateTests {
t.Run("", func(t *testing.T) {
rotated := pie.Rotate(test.ss, test.n)
assert.Equal(t, test.rotated, rotated)
})
}
}

0 comments on commit 4912a95

Please sign in to comment.