【问题标题】:Why is for-loop sometimes skipping some iterations?为什么 for-loop 有时会跳过一些迭代?
【发布时间】:2015-10-31 15:12:36
【问题描述】:

在下面的函数中,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;
}

JSFiddle

【问题讨论】:

  • 为什么是+0?似乎没有必要

标签: javascript loops for-loop while-loop


【解决方案1】:

您的问题在这里:

character = string.charAt(Math.floor(Math.random() * string.length-1) + 0); 

如果你的 rand 小于 0,你会得到一个负数,因此你不会得到任何字符。您必须像这样封装您的 string.length-1:

character = string.charAt(Math.floor(Math.random() * (string.length-1)));

更新小提琴:DEMO

永远记住:乘法先行!!

编辑:string.length is 36,您不需要减去 1,只需乘以

character = string.charAt(Math.floor(Math.random() * string.length));

【讨论】:

  • 这永远不会选择最后一个字符,因为随机是[0, 1)
【解决方案2】:

显示的循环不会“跳过”任何迭代,但会按照要求从[0, len) 开始迭代。

但是,charAt 的否定参数使它看起来像是“跳过”,因为"foo".charAt(-1) == ""。对于String.charAt 的任何越界,相同的空字符串结果都成立:

.. 如果您提供的索引 [to charAt] 超出范围,JavaScript 返回一个空字符串

产生始终有效索引的更正将仅仅是Math.floor(Math.random() * string.length)没有 -1。

虽然这有点偏颇(对于真正关心的人来说),但这是“正确的”,因为 Math.random 返回一个范围为[0, 1) 的数字。因此Math.random() * len[0, len) 返回一个值;并在地板之后的相同间隔中作为整数。

另外,最好选择更有用的变量名。正如 Ed 指出的那样,+0 是无关紧要的,因为Math.floor 返回一个(整数)数字。

【讨论】:

  • 感谢您的澄清。它完全按预期工作。 '有用的变量名'......怎么样?
  • @Devang 好吧,我知道这是一个“字符串”! (这可以看成Systems Hungarian Notation.的一种形式)让变量名告诉我它代表什么。像randomSetalphabet 之类的东西(当然不是严格地与“A-Z”英文字母相关,而是结果来自的字母)——尽管还有很多其他的,可能更好的名字可用。此更改将使变量名称“添加语义值”,从而“自记录”代码。
  • 一开始似乎有点复杂,但肯定会尝试实现它。谢谢!
【解决方案3】:

随机数有时为负数,这就是为什么在这些情况下一个字符是来自randomString 的船长。

https://jsfiddle.net/ojbp0evz/3/

Math.abs 为例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 2016-09-07
    • 2020-04-10
    相关资源
    最近更新 更多