0

I have a a position and an array of users

const position = 2
const users = ["John", "Mary", "Daniel", "Michael"]

I want to generate a new array (or reorder it) starting from the position.

In the case of position = 2 the generated array should be

users = ["Daniel", "Michael", "John", "Mary"]

In the case of position = 3 the generated array should be

users = ["Michael", "John", "Mary", "Daniel"]

In the case of position 0 (no changes) the generated array should left intact

const users = ["John", "Mary", "Daniel", "Michael"]

how can I achieve this?

ggorlen
  • 44,755
  • 7
  • 76
  • 106
handsome
  • 2,335
  • 7
  • 45
  • 73
  • What have you tried? Hint: [`Array#slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice). – ggorlen Mar 20 '20 at 23:57
  • Does this answer your question? [Rotate the elements in an array in JavaScript](https://stackoverflow.com/questions/1985260/rotate-the-elements-in-an-array-in-javascript) – ggorlen Mar 21 '20 at 00:23

4 Answers4

2

You could use map() or Array.from() to make a new array from the index + your offset using the modulus operator to wrap around:

const position = 2
const users = ["John", "Mary", "Daniel", "Michael"]

const rotate = (arr, position) => 
   Array.from(arr, (_, index) => arr[(index + position) % arr.length])


console.log(rotate(users, 0))
console.log(rotate(users, 1))
console.log(rotate(users, 2))
console.log(rotate(users, 3))
Mark
  • 90,562
  • 7
  • 108
  • 148
2

You can use Array#slice from 0..pos and from pos..length to divide the array into two chunks at the split index. Then swap the chunks and either spread or concat the two subarrays back together. Take the mod of the position to keep the rotation in-bounds.

const rotate = (arr, i) => {
  i %= arr.length;
  return [...arr.slice(i), ...arr.slice(0, i)];
};

for (let i = -1; i < 5; i++) {
  console.log(rotate(["John", "Mary", "Daniel", "Michael"], i));
}
ggorlen
  • 44,755
  • 7
  • 76
  • 106
0

Simple way to do that.

function reorder(arr, pos){
   var output = [];
   for(var i = pos;i<arr.length;i++){
      output.push(arr[i]);
   }

   for(var i = 0;i<pos;i++){
      output.push(arr[i]);
   }

   return output;
}

Not sure how efficient is this. There must be better ways to do this.

Dum
  • 1,431
  • 2
  • 9
  • 23
0

You can use a shift() + push() combinaison

users.push(users.shift());

...and then loop it by the position number.

const users = ["John", "Mary", "Daniel", "Michael"];
let position;

function rotate(array, index){
  for(let i = 0; i < index; i++){
    array.push(array.shift());
  }
  console.log(`Position: ${index}`);
  console.log(array);
}

// Test Zone
position = 0;
rotate(users, position);
position = 1;
rotate(users, position);
position = 2;
rotate(users, position);
position = 3;
rotate(users, position);
Wax
  • 605
  • 1
  • 5
  • 15