问题描述
在下面的函数中,for循环有时会跳过一次迭代。
在极少数情况下,我还发现它跳过了两次迭代。 如果我对for循环的理解仍然不完整,这有时会破坏我的代码,并可能影响我以后的代码。
我进一步调查了此事,并使用while循环进行了尝试,发现如果使用while循环,则不会发生此问题。
为什么for循环有时会跳过一些迭代?
function forLoopString(len)
{
var string = 'abcdefghijklmnopqrstuvwxyz0123456789';
var character = '',
randomString = '';
for (var i = 0; i < len; i++)
{
character = string.charAt(Math.floor(Math.random() * string.length-1) + 0);
randomString += character;
}
if(randomString.length < len)
{
console.log('Less than required length!');
randomString = randomString + '5';
}
return randomString;
}
1楼
所示的循环不会 “跳过”任何迭代,但会按照要求从[0, len)
进行迭代。
但是,对charAt
的否定参数使其看起来像“跳过”,因为"foo".charAt(-1) == ""
。
相同的空字符串结果适用于任何越界:
.. 如果您提供的[给charAt]的索引超出范围,则JavaScript 返回一个空字符串 。
产生始终有效索引的更正仅是Math.floor(Math.random() * string.length)
, 而没有 -1。
尽管这稍微有偏差(对于真正关心的人),但这是“正确的”,因为Math.random返回范围为[0, 1)
。
因此Math.random() * len
从[0, len)
返回一个值;
并在下限后的相同间隔内作为整数。
同样,最好选择更有用的变量名..并且,如Ed所指出的,+ 0是无关紧要的,因为Math.floor
返回一个(整数)数字。
2楼
随机数有时为负数,这就是在这种情况下字符从randomString
的原因。
例如,使用Math.abs
。
3楼
您的问题在这里:
character = string.charAt(Math.floor(Math.random() * string.length-1) + 0);
如果兰特小于0,您将得到一个负数,因此,您将不会得到任何字符。 您必须像这样封装string.length-1:
character = string.charAt(Math.floor(Math.random() * (string.length-1)));
更新的小提琴:
永远记住: 乘数第一!
编辑: string.length is 36
,您不需要减去1,只需相乘
character = string.charAt(Math.floor(Math.random() * string.length));