Andrew
Andrew

Reputation: 238997

How to shift/rotate an array of items to a specific index in a JavaScript array?

I have a jQuery collection of elements (images).

var images = $('img');

I want to alter the collection so that it starts at a specific index, and the previous items are appended to the end. Sort of like a Rolodex.

I could also convert them to an array if necessary. An example of this with a JavaScript array:

var images = ['image0', 'image1', 'image2', 'image3'];
// rotate through to index 2
// images should == ['image2', 'image3', 'image0', 'image1']

Upvotes: 2

Views: 2638

Answers (5)

Saurabh Chandra Patel
Saurabh Chandra Patel

Reputation: 13644

var data_all= ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul" , 'Aug' ,'Sep' , 'Oct' , 'Nov' , 'Dec'];
data_all.push(data_all.shift());

Upvotes: 0

JerryCauser
JerryCauser

Reputation: 885

If you need smart sort function, then you can put function into sort as argument with your algorithm. For your task it can be like that:

var images = ['image5','image0', 'image1', 'image2', 'image3','image4'];
var magicNum = 2 -1;//your offset with shift = 1
images.sort(function(a,b){
  a = parseInt(a.substr(5))-magicNum,
  b = parseInt(b.substr(5))-magicNum;
  
  if(a*b<=0) return a>0?-1:b>0?1:0;
  else return a-b;
});

document.body.textContent = images.join(", ");

It can be used even on big nonsorted dynamic arrays. Also this method more scalable than method with splice and push.

Upvotes: 1

void
void

Reputation: 36703

var arr = [2,3,4,5,6,7];

function rot(arr, ind)
{
    var narr = [];
 var len = arr.length;
 for(var i=0; i<arr.length; i++)
 {
     narr.push((i+ind<len?arr[i+ind]:arr[len-i-1]));
 }
    return narr;
}

rot(arr,2); // returns 4,5,6,7,2,3

Upvotes: 0

Zlatko
Zlatko

Reputation: 19578

If it was an array, it's trivial with Array.splice:

> x = ['image0', 'image1', 'image2', 'image3'];
[ 'image0',
  'image1',
  'image2',
  'image3' ]
> x = x.splice(2).concat(x)
[ 'image2',
  'image3',
  'image0',
  'image1' ]
> x = ['image0', 'image1', 'image2', 'image3'];
[ 'image0',
  'image1',
  'image2',
  'image3' ]
> x = x.splice(3).concat(x)
[ 'image3',
  'image0',
  'image1',
  'image2' ]
> 

Splice does in-place chopping out of stuff, what you're left with is the spliced first two elements. We put that into X. The original array is modified in place, so it points to what it was at the original referencing time, so, the remaining n elements. So you concat to those remaining elements the spliced first two.

You can even use negative values and play with it, move forward and backward:

> x = ['image0', 'image1', 'image2', 'image3'];
[ 'image0',
  'image1',
  'image2',
  'image3' ]
> x = x.splice(-1).concat(x)
[ 'image3',
  'image0',
  'image1',
  'image2' ]
> x = x.splice(1).concat(x)
[ 'image0',
  'image1',
  'image2',
  'image3' ]
> x = x.splice(-3).concat(x)
[ 'image1',
  'image2',
  'image3',

Upvotes: 3

Lye Fish
Lye Fish

Reputation: 2578

For the Array, you could do this:

images.push.apply(images, images.splice(0, i));

var images = ['image0', 'image1', 'image2', 'image3'];
var i = 2;


images.push.apply(images, images.splice(0, i));


document.body.textContent = images.join(",");

There's a limit to how many items can be passed to .apply(), but it's in the thousands. If that's an issue, then you can push individual items from the .splice() in.

Upvotes: 4

Related Questions