【问题标题】:Browser Freezing on Loop Run (JavaScript)循环运行时浏览器冻结 (JavaScript)
【发布时间】:2017-05-20 14:11:04
【问题描述】:

我正在尝试随机重建一段单词而不在 JavaScript 中重复相同的单词:

var  para = 'dashing through the snow' +
        ' in a one horse open sleigh' +
        ' over the fields we go' +
        ' laughing all the way';
console.log(para);
function getRandomNumber(min, max) 
{
     return Math.floor(Math.random() * (max - min)) + min;
}

var words = para.split(' ');
var newPara = '';

for(var i = 0; i < words.length - 1; i++)
{
  var curWord = words[getRandomNumber(0,words.length - 1)];

  if(newPara.indexOf(curWord) == -1)
  {
    newPara += curWord + ' ';
    console.log(newPara);
  } else
  {
    i--;
  }

}

代码将一个段落拆分为一个单词数组(总共 19 个)。然后我使用循环遍历这个数组并随机选择一个单词,检查该单词是否已添加到 newPara 字符串中。如果没有,我添加它。如果有,我从循环运行中减去 1。问题是当我使用 else 语句从循环中减去一个时,脚本会导致浏览器冻结。感谢您对此问题的任何帮助。

基于 cmets 我做了这个编辑:

if(newPara.length <= words.length)
    {
    if(newPara.indexOf(curWord) == -1)
    {
      newPara += curWord + ' ';
      console.log(newPara);
    } else
    {
      i--;
    }
  }

但是,我仍然遇到同样的错误。

【问题讨论】:

  • 您从数组的长度中减去 1,但从不减小数组本身的大小 - 它是无限的。
  • else { i--; } 的目的是什么?
  • else { i-- } 如果单词已经存在于新段落中,将从循环运行中减一。 @Press 我明白你在说什么。您的意思是:words[getRandomNumber(0,words.length - 1)]; 还是您的意思是 i--;

标签: javascript loops for-loop random


【解决方案1】:

我想出的解决方案是从 words.length 向后工作到 0,如果已经使用过,则从数组中删除它。

Fiddle

var para = 'dashing through the snow' +
  ' in a one horse open sleigh' +
  ' over the fields we go' +
  ' laughing all the way';

function getRandomNumber(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

var words = para.split(' ');
var newPara = '';

for (var i = words.length; i > 0; i--) {

  var rand = getRandomNumber(0, words.length - 1),
    curr = words[rand];

  if (newPara.indexOf(curr) == -1) {
    newPara += curr + ' ';
    words.splice(rand, 1);
  }

}

console.log(newPara);

【讨论】:

  • 唯一剩下的问题是修复@Y.C.提到的重复单词问题。以下。例如,“the”被列出了 3 次。我应该以 19 字的段落结尾,但我只会以 13 字的段落结尾。
  • 哦!使用此代码,我根本不需要 if 语句。 words.splice 删除项目的索引,因此它不会再次出现。非常感谢!
【解决方案2】:

您正在创建的是一个无限循环。如果随机数生成器再选择一个已经使用的单词 2 次,则循环计数器减 2。最终,当所有单词都被使用时(假设只选择了 1 或 2 次)你的 i总是小于words.length(因此,条件永远不会满足)。

一个可能的解决方案是将段落的长度保存在一个变量中,并在循环条件中使用它。然后,对于您选择的每个单词,将其从 words 数组中删除。

这不会以无限循环告终,并且还会最大限度地减少您的迭代次数,因为在尝试查找单词时不会再有遗漏。

【讨论】:

    【解决方案3】:

    试试这个代码:

    var para = 'dashing through the snow' +
        ' in a one horse open sleigh' +
        ' over the fields we go' +
        ' laughing all the way';
    var words, newPara = '';
    console.log(para);
    
    words = para.split(' ');
    
    words.sort(function(a, b) {
        return 0.5 - Math.random();
    });
    
    newPara = words.join(' ');
    console.log(newPara);
    

    您的代码中的问题是您的 para 中的某些单词重复了多次,例如单词“the”出现了 3 次,它永远不会满足条件:i === words.length - 1

    var  para = 'dashing through the snow' +
        ' in a one horse open sleigh' +
        ' over the fields we go' +
        ' laughing all the way';
    

    您的随机数生成算法中还有一个错误,这使得获取最后一个数字words[words.length-1] 变得非常困难,将getRandomNumber(0, words.length - 1) 更改为getRandomNumber(0, words.length) 将使其工作。

    【讨论】:

    • 你能给我解释一下这两个项目吗:words.sort(function(a, b) { return 0.5 - Math.random(); });newPara = words.join(' ');
    • MDN中有引用,Array.prototype.sort()link,Array.prototype.join()link
    • join() 方法将数组的所有元素连接成一个字符串。sort() 方法根据您提供的方法对数组元素进行适当的排序并返回数组。
    • 我明白了。我一直在寻找一种在每次刷新页面时随机生成段落的顺序词的方法。听起来这些方法不会那样做吗?因此问题。但也许我错过了什么。
    • 我的代码是一个简单的实现方式,你可以试试,基本上它会打乱句子。
    猜你喜欢
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 2016-12-10
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多