3

I have some code that loops through a collection of list elements and a collection of colours. It makes sure each list element is designated to a colour.

I understand everything about this apart from the modulus operator. I get that it finds and uses the remaining number, but I cannot for the life of me understand what it is doing here?

var li = document.getElementsByTagName('li');
var colors = ["salmon", "teal", "orange", "grey", "blue"];
var colorsCount = colors.length;

for ( var i = 0; i < li.length; i++ ) {
    li[i].style.backgroundColor = colors[ i % colorsCount  ]; // why does this work?
}

8 Answers8

5

Since there is (potentially) a larger number of items in the li array, this prevents i from being outside the bounds of the colors array, since i % colorsCount can never be over colorsCount.

For example, if we had 10 elements in li, and 5 colors, i % colorsCount would be:

i     i % colorsCount     Color
-------------------------------
0     0                   salmon
1     1                   teal
2     2                   orange
3     3                   grey
4     4                   blue
5     0                   salmon
6     1                   teal
7     2                   orange
8     3                   grey
9     4                   blue

More Information on Modulo Operations.

Mike Christensen
  • 88,082
  • 50
  • 208
  • 326
  • Okay. But why would it never be over colorsCount? I can see from the table but I can't understand the logic. –  Sep 10 '13 at 21:50
  • 1
    The modulus operator divides the value of one expression by the value of another, and returns the remainder. How could a remainder (the left over amount) ever be more than the right operand? – Mike Christensen Sep 10 '13 at 21:54
  • 1
    For example, `27 % 5` is 2, because `27 / 5` is 5 with a remainder of 2 (yea, remember the lame way we'd do division in elementary school?) – Mike Christensen Sep 10 '13 at 21:55
  • Oh that's very interesting. How come it prints out in a chronological order? (0, 1, 2, 3, 4) –  Sep 10 '13 at 22:04
  • Because `i` is being incremented by `1` after each iteration, thus the remainder would also be one more each time. Until the next number which is evenly divisible (5, 10, 15, 20, etc), at which point the remainder becomes `0` again and the pattern repeats. I'd skim the [Wikipedia article](http://en.wikipedia.org/wiki/Modulo_operation) to perhaps get a better overview if things still aren't making sense. – Mike Christensen Sep 10 '13 at 22:08
1

i % colorsCount will set the bound of the index to be between 0 and colorsCount-1, thus ensuring you never index past the end of the array.

Since mod is the remainder, the remainder can never be greater than the divisor (which in this case, is the length of the array).

Alan
  • 45,915
  • 17
  • 113
  • 134
0

You iterate from 0 until how many li elements you have. For this example, say 10.

You then look at the colors array and find the element for that iteration (i) and modulus by how many items are in the colors array.

In short, this is what's happening:

var colorsCount = 10;

1 % 10 = 1 // ... Access colors[1]; (teal)
2 % 10 = 2 // .... Access colors[2]; (orange)
3 % 10 = 3 // .... Access colors[3]; (grey)
4 % 10 = 4 // .... Access colors[4]; (blue)
5 % 10 = 5 // .... Access colors[5];

etc

If you are wondering why it will never access an element outside of the array, the answer is because as i becomes greater, the result becomes smaller.

For example, take iteration 8:

   8 % 5 = 3

(Iteration 8, 5 elements in the array)

Therefore you are accessing colors[3];

Darren
  • 68,902
  • 24
  • 138
  • 144
0

Perhaps this snippet may help you understand:

var s = ''
for (var i = 0; i < 20; i ++) {
    s += (i % 5) + ', '
}
console.log(s)

The result is:

0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 

Note how the number resets to 0 every time it reaches 5. The % colors.length just makes sure the index never goes above the array's length.

A more descriptive way of understanding:

0 % 5: 0/5 = 0, remainder 0
1 % 5: 1/5 = 1/5, remainder 1
...
5 % 5: 5/5 = 1, remainder 0
6 % 5: 6/5 = 1 1/5, remainder 1
7 % 5: 7/5 = 1 2/5, remainder 2
...
tckmn
  • 57,719
  • 27
  • 114
  • 156
0

It's cycling your colours. Because you only have a limited number of colours, and any number of possible list items, it makes sure that i will not overflow the bounds of your colors array.

paddy
  • 60,864
  • 6
  • 61
  • 103
0

The modulus operator returns the remainder of division. It allows you to loop through and reuse the colors array even though there are potentially less colors in the array than there are elements in your list to color.

If length is say 8,

5 % 1 == (5 / 1) = 0 remainder 1
5 % 2 == (5 / 2) = 0 remainder 2
5 % 3 == (5 / 3) = 0 remainder 3
5 % 4 == (5 / 4) = 0 remainder 4
5 % 5 == (5 / 5) = 1 remainder 0
5 % 6 == (5 / 6) = 1 remainder 1
5 % 8 == (5 / 7) = 1 remainder 2
5 % 7 == (5 / 8) = 1 remainder 3

As you can see, the remainders are what's returned by the mod operator, and they're always less than the length of the colors array.

PherricOxide
  • 15,493
  • 3
  • 28
  • 41
0

why does i % colorsCount work?

What it does

This code cycles through colors. It does so using the modulus operator to ensure you're always within the bounds of the array.

How it does it

Modulus operation finds the remainder of division of one number by another.

In your case by taking i modulus the colorsCount:

0 % 5; // 0
1 % 5; // 1
1 % 5; // 2
3 % 5; // 3
4 % 5; // 4
5 % 5; // 0
8 % 5; // 3
Jason McCreary
  • 71,546
  • 23
  • 135
  • 174
0

The result of a modulus operation is the remainder after division of the left operand by the right operand.

So the line of code in question will always return some number between 0 and colorsCount-1.

mrtig
  • 2,217
  • 16
  • 26