# Rotate the elements in an array in JavaScript

EDIT::
Hey so turns out there’s too much iteration happening. No loops, no branching.

Still works with negative n for right rotation and positive n for left rotation for any size n,
Mutation free

``````function rotate(A,n,l=A.length) {
const offset = (((n % l) + l) %l)
return A.slice(offset).concat(A.slice(0,offset))
}
``````

Here’s the code golf version for giggles

``````const r = (A,n,l=A.length,i=((n%l)+l)%l)=>A.slice(i).concat(A.slice(0,i))
``````

EDIT1::*
Branchless, mutationless implementation.

So hey, turns out I had a branch where I didn’t need it. Here is a working solution.
negative num = right rotate by |num|
positive num = left rotate by num

``````function r(A,n,l=A.length) {
return A.map((x,i,a) => A((((n+i)%l) + l) % l))
}
``````

The equation `((n%l) + l) % l` maps exactly positive and negative numbers of any arbitrarily large values of n

ORIGINAL

Rotate left and right. Rotate left with positive `n`, rotate right with negative `n`.

Works for obscenely large inputs of `n`.

No mutation mode. Too much mutation in these answers.

Also, fewer operations than most answers. No pop, no push, no splice, no shift.

``````const rotate = (A, num ) => {
return A.map((x,i,a) => {
const n = num + i
return n < 0
? A((((n % A.length) + A.length) % A.length))
: n < A.length
? A(n)
: A(n % A.length)
})
}
``````

or

`````` const rotate = (A, num) => A.map((x,i,a, n = num + i) =>
n < 0
? A((((n % A.length) + A.length) % A.length))
: n < A.length
? A(n)
: A(n % A.length))

//test
rotate((...Array(5000).keys()),4101)   //left rotation
rotate((...Array(5000).keys()),-4101000)  //right rotation, num is negative

// will print the first index of the array having been rotated by -i
// demonstrating that the rotation works as intended
(...Array(5000).keys()).forEach((x,i,a) => {
console.log(rotate(a,-i)(0))
})
// prints even numbers twice by rotating the array by i * 2 and getting the first value
//demonstrates the propper mapping of positive number rotation when out of range
(...Array(5000).keys()).forEach((x,i,a) => {
console.log(rotate(a,i*2)(0))
})
``````

Explanation:

map each index of A to the value at index offset. In this case

``````offset = num
``````

if the `offset < 0` then `offset + index + positive length of A` will point to the inverse offset.

if `offset > 0 and offset < length of A` then simply map the current index to the offset index of A.

Otherwise, modulo the offset and the length to map the offset in the bounds of the array.

Take for instance `offset = 4` and `offset = -4`.

When `offset = -4`, and `A = (1,2,3,4,5)`, for each index, `offset + index` will make the magnitude (or `Math.abs(offset)`) smaller.

Let’s explain the calculation for the index of negative n first. `A((((n % A.length) + A.length) % A.length)+0)` and been intimidated. Don’t be. It took me 3 minutes in a Repl to work it out.

1. We know `n` is negative because the case is `n < 0`. If the number is larger than the range of the Array, `n % A.length` will map it into the range.
2. `n + A.length` add that number to `A.length` to offset n the correct
amount.
3. We know `n` is negative because the case is `n < 0`. `n + A.length` add that number to `A.length` to offset n the correct amount.
4. Next Map it to the range of the length of A using modulo. The second modulous is necessary to map the result of the calculation into an indexable range

5. First index: -4 + 0 = -4. A.length = 5. A.length – 4 = 1. A2 is 2. Map index 0 to 2. `(2,... )`

6. Next index, -4 + 1 = -3. 5 + -3 = 2. A2 is 3. Map index 1 to 3. `(2,3... )`
7. Etc.

The same process applies to `offset = 4`.
When `offset = -4`, and `A = (1,2,3,4,5)`, for each index, `offset + index` will make the magnitude bigger.

1. `4 + 0 = 0`. Map A(0) to the value at A(4). `(5...)`
2. `4 + 1 = 5`, 5 is out of bounds when indexing, so map A2 to the
value at the remainder of `5 / 5`, which is 0. A2 = value at
A(0). `(5,1...)`
3. repeat.