Let’s say you have an array of items. They might be colours, pieces of text, DOM nodes, whatever. However, you want to loop around them infinitely. To further exemplify, if you have an array of 8 items, and you are currently on item 2 and you skip along 10, we want to end up back at slot 4 and not a non-existent slot 12. This is standard behaviour for carousels and the like.

This is a scenario I’ve come across a few times in the last year or so and as I keep having to remember how to solve the problem I’m writing it out here for developer posterity.

The modulos/remainder operator

The key to solving this problem is the Modulo operator, also known as the Remainder operator and expressed in JavaScript with the % symbol. This operator is used to get the remainder after a division.

In English we might say that the remains of dividing 8 by 3 is 2 as we can get two lots of 3 out of 8 giving us 6 and there are then 2 remaining.

Let’s look at this in JavaScript:

var remainsOfEightByThree = 8 % 3; 
console.log(remainsOfEightByThree); // 2


Let’s do another example just to be clear what’s going on. What about the remains of dividing 13 by 4?

We can get 3 whole lots of 4 out of 13 which takes us to 12 so we would expect the remains to be 1. Here again in JavaScript:

var remainsOfThirteenByFour = 13 % 4; 
console.log(remainsOfThirteenByFour); // 1


OK, so how do use this to solve our looping around problem?

Looping around an array with modulos/remainder operator

Let’s look at an array of colour values:

var colours = ["EC6060", "4DB52E", "31D1B3", "1D9DCB", "1D3ACB","AD70CC", "E84F82"];


We are going to make a div change colour from one colour value to another by taking the existing slot number and adding any number to it. So, say for example, we take the scenario given in the first paragraph, we are at slot 2 (in JS that would be the third value as JS is zero-indexed), which is the value 31D1B3 and we try and skip forward 10 slots. We don’t want to select a non-existent slot 12, we want to end up back at slot 5, with the value AD70CC.

‘zero-indexed’ simply means that counting starts at 0 and not 1. In JavaScript Arrays the first slot is always item 0. So yourArray[0] would select your first item whereas yourArray[1] would actually select the second one.

The solution

Here’s the final solution. Take a look and then we will step through what’s going on.

See the Pen
Remainder/Modulos example
by Ben Frain (@benfrain)
on
CodePen.

var item = document.querySelector(".item");
var readout = document.querySelector(".readout");
var colours = ["EC6060", "4DB52E", "31D1B3", "1D9DCB", "1D3ACB","AD70CC", "E84F82", "CB1212"];

var count = 0;
setInterval(e => {
    var randomNumber = Math.floor(Math.random()*11);
    count = (count + randomNumber) % colours.length;
    var newColour = colours[count];
    readout.innerHTML = `We added <b>${randomNumber}</b>, meaning the new slot number to display is <b>${count}</b>, meaning a colour value of <b>${newColour}</b>`
    item.style.backgroundColor = `#${newColour}`;   
}, 3000);


Some of this is surplus to the job at hand as it is just to get things reading out on screen.

In essence, every 3 seconds, we generate a random number between 0–10 and add that to the existing count (which starts at 0). The magic part, that makes the array loop around is this:

count = (count + randomNumber) % colours.length;


Here we re-assign our count to be: the remains of the current count plus the new random number divided by the length of the array. So, given our 8 slot colours array, if we were on slot 0, the random number was 9 the calculation would be:

count = (0 + 9) % 8 // result would be 1


Our modulus operator forces the resultant number to be something that is the result of a clean division of the array we are working on. In practice this means we loop around the array as the number can never be greater than the array length.

Summary

Looping infinitely around an array, rather than merely through it, is something I’ve had to do an inordinate number of times recently, particularly when animating elements. Understanding the remainder/modulus operator is key to solving the issue elegantly in JavaScript.