iamnotoriginal
iamnotoriginal

Reputation: 457

Efficient way to circle through an array?

I'm wondering if there is a more effective way of circling through an array. For my purposes, the array is holding image sources. When the last image is shown and the next button is pushed it circles back to the first image. If the previous button is pushed on the first image it circles to the last image.

This is what I was able to come up with, but I feel there's a more efficient way to go about it.

var marker = 0;

// Circle through an array.
function moveMarker(array, action, direction) {
    if (!direction) {
        if(marker == array.length - 1)
            marker = -1;
        marker += 1;
        action();
    }

    else {
        if (marker == 0)
            marker = array.length;
        marker -=1;
        action();
    }
}

Upvotes: 4

Views: 2976

Answers (3)

guypursey
guypursey

Reputation: 3184

Declare a local variable upfront to take care of the last position of your array and then use the ternary operator to determine what should be done with marker. The ternary operator basically allows you perform a conditional on the same line as you perform an operation. After that, you should only need one call for action().

function moveMarker(array, action, direction) {
    var a = array.length - 1;

    if (!direction) {
        marker += (marker === a) ? -(a) : 1;
    } else {
        marker += (marker === 0) ? (a) : -1;
    }

    action();
};

EXTRA TIP: You might also want to look at putting these functions (i.e., moveMarker() and action()) into a single object as methods so that you're not declaring and changing a global variable like marker. But without knowing the rest of your code, I don't if this approach would work for you or not.

Upvotes: 0

Phil H
Phil H

Reputation: 20141

Firstly, you can simplify the if/else using maths, and remove the bounds checking using modulo.

var marker = 0;

// Circle through an array.
function moveMarker(array, action, direction) {
    var increment = direction ? 1 : -1;
    marker = Math.modulo(marker + increment, array.length);        
    action();
}

I would suggest, however, incorporating marker into an object, rather than having a global variable:

function markerMover(array, action, direction) {
    var marker = 0;
    function next() {
        var increment = direction ? 1 : -1;
        marker = Math.modulo(marker + increment);        
        action();
    }
}
var mover = new markerMover(someArray, someAction, someDirection);
mover.next()
// or even
var intervalHandle = setInterval(mover.next, 25);

Upvotes: 1

Guffa
Guffa

Reputation: 700342

Yes, you can use the % modulo operator:

var marker = 0;

// Circle through an array.
function moveMarker(array, action, direction) {
    if (!direction) {
        marker = (marker + 1) % array.length;
    }
    else {
        marker = (marker + array.length - 1) % array.length;
    }
    action();
}

or even:

var marker = 0;

// Circle through an array.
function moveMarker(array, action, direction) {
    marker = (marker + array.length + (direction ? -1 : 1)) % array.length;
    action();
}

Upvotes: 11

Related Questions