Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using shift() and push() to loop array values vs. using a counter variable, what is the best approach?

Tags:

javascript

I'm looping through a set of images within an array of animation frames. There are 7 images, and looping from 1-7 completes the animation. I need this animation to loop indefinitely, but I was wondering which of these is the best approach:

Loop by modifying array

/* Pull image from start of array. */
var image = frames.shift();
/* Process image. */
...
/* Add image back to end of array. */
frames.push(image );

Loop using counter variable

/* Pull image by counter offset. */
var image = frames[counter];
/* Process image. */
...
/* Increment or reset counter value. */
counter + 1 === frames.length ? counter = 0 : counter = counter + 1;

Is there a reason I'd chose one over the other? Alternatively, is there a better approach to this?

like image 956
James Donnelly Avatar asked Jan 13 '23 17:01

James Donnelly


2 Answers

Modifying the array is going to be more expensive than simply using a variable to keep track of your position in the array. The better way to do this, if you're looping indefinitely, seems to just be to use a while loop (rather than using a for loop where you reset the counter inside):

var i = 0;
while (true) {
    doSomething to array[i];

    i = (i+1) % array.length;
}

However if your goal really is having an animation proceed indefinitely every time a given interval elapses, a loop isn't ideal at all. Use setInterval instead.

var frames = ...; //your images
var i = 0;
function animate() {
    do something to frames[i];
    i = (i+1) % array.length;
}

setInterval(animate, time_between_runs);

where time_between_runs is how much time should elapse before the function is called again.

like image 69
nbrooks Avatar answered Feb 13 '23 17:02

nbrooks


Alternatively a circular linked list also can be used I think. To turn an array of objects into a circular linked list:

frames.forEach(function(elem, index) { 
    elem.next = frames[index + 1] || frames[0];
});

And now you can do something like this:

setInterval(function() {
    frame = frame.next;
    ....
}, delay);
like image 42
Zoltan.Tamasi Avatar answered Feb 13 '23 17:02

Zoltan.Tamasi