理解取模运算符

3
我有一些代码,通过一个列表元素集合和一个颜色集合进行循环。它确保每个列表元素都指定了一种颜色。
除了取模运算符,我对这段代码的理解都很清晰。我知道它可以找到并使用剩余的数字,但是我无法弄清楚它在这里究竟做了什么?
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?
}

2
5分钟内得到8个答案,Stack Overflow 真是太棒了。 - OJay
@OJay 这是一个非常简单的问题 :) - tckmn
8个回答

5

由于li数组中可能有更多的项,因此这可以防止i超出colors数组的范围,因为i%colorsCount永远不会超过colorsCount

例如,如果我们有10个元素在li中,以及5种颜色,i%colorsCount将是:

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

更多关于模运算的信息。


好的。但为什么它永远不会超过colorsCount?我可以从表中看到,但我无法理解其逻辑。 - user1469270
1
模数运算符将一个表达式的值除以另一个表达式的值,并返回余数。 余数(剩余的量)怎么可能比右操作数还要多? - Mike Christensen
1
例如,27%5是2,因为27/5是5余2(是的,还记得我们在小学时做除法的笨方法吗?) - Mike Christensen
哦,那很有趣。为什么它按照时间顺序打印出来?(0、1、2、3、4) - user1469270
因为在每次迭代后i都会增加1,因此余数也会随之增加1。直到下一个可以被整除的数字(5、10、15、20等),此时余数再次变为0并且模式重复。如果仍然不理解,建议阅读一下维基百科文章以获得更好的概述。 - Mike Christensen

1

i % colorsCount将设置索引的边界为0至colorsCount-1,从而确保您永远不会越过数组的末尾。

由于模是余数,余数永远不会大于除数(在这种情况下,是数组的长度)。


0

你需要从0开始迭代,直到你有多少个li元素。就这个例子来说,假设是10个。

然后你看一下colors数组,找到那次迭代(i)对应的元素,并对colors数组中的项目数量取模。

简而言之,发生了以下情况:

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];

如果你想知道为什么它永远不会访问数组外的元素,答案是因为随着i变得更大,结果变得更小。

例如,看看第8次迭代:

   8 % 5 = 3

(迭代8,数组中有5个元素)

因此,您正在访问colors [3];


0

也许这段代码片段可以帮助您理解:

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

结果是:

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

请注意每次到达“5”时数字如何重置为“0”。 “%colors.length”只是确保索引永远不会超过数组的长度。
更具描述性的理解方式:
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
...

0

它正在循环你的颜色。因为你只有有限数量的颜色,而任意数量的列表项,它确保 i 不会超出你的 colors 数组的边界。


0

模数运算符返回除法的余数。即使颜色数组中可能比要着色的列表中的元素少,它也允许您循环遍历和重复使用颜色数组。

例如长度为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

正如您所看到的,余数是由模运算符返回的,它们始终小于颜色数组的长度。


0
为什么 i % colorsCount 能够工作?
它的作用是循环遍历 colors 数组。使用模运算符可以确保始终在数组范围内进行操作。
具体实现方式是通过模运算找到一个数除以另一个数的余数。
在你的代码中,通过对 i 取模 colorsCount 来实现:
0 % 5; // 0
1 % 5; // 1
1 % 5; // 2
3 % 5; // 3
4 % 5; // 4
5 % 5; // 0
8 % 5; // 3

0

模数运算的结果是左操作数除以右操作数的余数。

因此,所讨论的代码行将始终返回0到colorsCount-1之间的某个数字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接