【问题标题】:Algorithm stops and I don't have no idea why算法停止,我不知道为什么
【发布时间】:2019-03-16 17:32:39
【问题描述】:

嘿!我正在尝试使用 HTML、CSS 和 Javascript 编写 Pexeso 代码。我有随机生成函数(数字不能使用超过一次 - 我用数组解决了这个问题)。然后我有另一个函数调用上述函数并通过返回的 img 元素的编号 id 进行选择并设置图像源。一切看起来都正确 - IDE 和 Google Chrome 不会返回任何错误,但它仍然没有做正确的事情 - 它永远不会获取所有图像。

我正在放置代码并筛选编译后的外观。

HTML

<!DOCTYPE html>
<html lang='cs'>
  <head>
    <title></title>
    <meta charset='utf-8'>
    <link href='style.css' rel='stylesheet' type='text/css'>
  </head>
  <body>
  <div class="container">
    <img class="pexeso" src="" id="1">
    <img class="pexeso" src="" id="2">
    <img class="pexeso" src="" id="3">
    <img class="pexeso" src="" id="4">
    <img class="pexeso" src="" id="5">
    <img class="pexeso" src="" id="6">
    <img class="pexeso" src="" id="7">
    <img class="pexeso" src="" id="8">
    <img class="pexeso" src="" id="9">
    <img class="pexeso" src="" id="10">
    <img class="pexeso" src="" id="11">
    <img class="pexeso" src="" id="12">
    <img class="pexeso" src="" id="13">
    <img class="pexeso" src="" id="14">
    <img class="pexeso" src="" id="15">
    <img class="pexeso" src="" id="16">       
  </div>
  <script src='app.js'></script>
  </body>
</html>

JS

var position;
position = new Array();

function generateNumber(){
//generates random number between 0 and 15
var number = Math.round(Math.random()*15)+1;

//checks if number is already used
for (var i = 0; i <= position.length; i++){
    if (position[i] == number){
        generateNumber();
    }

//returns number
    console.log(number);
    position.push(number);
    return number;
}
}

function mixPexeso(){
for (var i = 0; i <= 7; i++){
//sets images to their location and type their position
    var firstImage = generateNumber();
    var secondImage = generateNumber();
    var image = 'img/image-'+i+'.png';

    document.getElementById(firstImage).src = image;
    document.getElementById(secondImage).src = image;
    }
}

mixPexeso();

屏幕:https://prnt.sc/l4wr1q

【问题讨论】:

  • if (position[i] == number){ generateNumber(); } 可能需要是 if (position[i] == number){ number = Math.round(Math.random()*15)+1 } 我会想到的。否则,您将丢弃新尝试生成数字的结果。但我也不认为你需要重新运行整个 generateNumber() 函数,这似乎有点矫枉过正,你只需要一个新的随机数
  • 有更好的方法可以在一个范围内随机生成数字并且它们只使用一次。生成可用数字的数组,随机排序,取出第一个索引。
  • 你需要return generateNumber();

标签: javascript html function return


【解决方案1】:

问题:

当你发现号码已经存在时,你应该打破循环并返回generateNumber的结果:

if (position[i] == number) {
    return generateNumber();
}

替代方式:

无论如何,函数generateNumber 可以通过删除递归调用并将整个事物包装在 IIFE 中进行封装以更好的方式实现:

var generateNumber = (function() {
  var numbers = [];

  return function() {
    var number;
    do {
      number = Math.floor(Math.random() * 16);
    } while(numbers.includes(number));
    numbers.push(number);
    return number;
  }
})();

最佳方式:

更好的方法是用数字(0 到 15)预填充数组,将它们打乱,然后每次调用函数时,您只需 popshift 该数组中的一个数字:

var generateNumber = (function() {
  var numbers = [];

  for(var i = 0; i < 16; i++) numbers.push(i);

  for(var i = 0; i < 16; i++) {
    var randIndex = Math.floor(Math.random() * 16);
    var temp = numbers[i];
    numbers[i] = numbers[randIndex];
    numbers[randIndex] = temp;
  }

  return function() {
    return numbers.pop();
  }
})();

【讨论】:

  • 我使用了第三个选项,它有效,非常感谢。但是,我想了解整个代码。除了返回函数和最后的圆括号之外,我了解所有内容。抱歉,如果我听起来很愚蠢,但我是 javascript 的新手,而且我之前没有遇到过这个问题 - 我总是擅长简单的返回,这不在他自己的函数中。
  • @ondrejhadrava 不客气!这些被称为 IIFE(I立即I调用Function Expression)。代码不需要工作。这个概念是包含所有代码的函数立即被调用(因此在末尾的圆括号),并将其返回值分配给generateNumber,因此返回一个函数。代码封装在 IIFE 中,作为封装外部范围变量(准确地说是变量 numbers)的一种方式。
  • @ondrejhadrava 在您的代码中,您将position 定义为全局变量,但它仅供generateNumber 使用。最好将其从全局范围中隐藏起来,并且只允许generateNumber 访问,你不觉得吗?我们不能只在generateNumber 中声明它,因为显而易见的原因这不起作用。所以我们将它与generateNumber 一起包装在另一个函数(IIFE)中。我们可以给 IIFE 起个名字,然后像普通函数一样调用它,但它只需要调用一次,那何必呢?因此,我们只是在它被定义后立即调用它。
  • @ondrejhadrava 从这个 IIFE 返回的函数是 generateNumber,我们真的不需要命名它,所以它保持匿名。一旦调用 IIFE,它将被分配给变量 generateNumber,因此我们将使用外部变量 (generateNumber) 来调用它。由于闭包,此函数可以访问变量numbers
  • @ondrejhadrava 在此other SO question 中了解更多关于 IIFE 的信息。另请阅读模块模式,这是 IIFE 的主要用途,here。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多