当在 Javascript 中使用许多 for 循环时,输出是未定义的

When many for loops are used in Javascript, output is undefined

本文关键字:输出 未定义 循环 for Javascript 许多 当在      更新时间:2023-09-26

如 https://jsfiddle.net/LBMF_1/gacLzLnn/所示,我的代码表面上生成了8位数字的所有可能的排列,使用for循环中的for循环。在问题结束时)我的代码在语法上似乎是正确的,因为 JSHint 和 chrome 控制台都没有错误。这是我的错误,还是由JS引起的常见问题?可能是前者,因为这似乎应该有效积分:还有哪些其他方法可以避免嵌套的 for 循环?你不知道我有多感谢任何帮助。另外,堆栈溢出和新段落是怎么回事?代码在这里,在我看来,运行时应该在控制台中粘贴一个很长的数字列表,但会出现很多"未定义"的数字。

var generator = function() {
  listofavailable = listofavailablereset;
  fullarray = [];

  for (i = 7; i > 0; i--) {
    numgen = "";
    inum = listofavailable[i];
    listofavailable.splice(i, 1);
    numgen = inum;
    for (v = 6; v > 0; v--) {
      vnum = listofavailable[v];
      listofavailable.splice(v, 1);
      numgen = numgen.concat(vnum);
      console.log(numgen);
      for (c = 5; c > 0; c--) {
        cnum = listofavailable[c];
        listofavailable.splice(c, 1);
        numgen = numgen.concat(cnum);
        for (g = 4; g > 0; g--) {
          gnum = listofavailable[g];
          listofavailable.splice(g, 1);
          numgen = numgen.concat(gnum);
          for (k = 3; k > 0; k--) {
            knum = listofavailable[k];
            listofavailable.splice(k, 1);
            numgen = numgen.concat(knum);
            for (b = 2; b > 0; b--) {
              bnum = listofavailable[b];
              listofavailable.splice(b, 1);
              numgen = numgen.concat(bnum);
              for (j = 1; j > 0; j--) {
                jnum = listofavailable[j];
                listofavailable.splice(j, 1);
                numgen = numgen.concat(jnum);
                fullarray = fullarray + numgen;
              }
            }
          }
        }
      }
    }
  }
};

这是一个基于你的小提琴的修改实现。请注意,您的示例中缺少数字"0"和"5",我不确定这是否是有意的。

var listofavailable = ['1', '2', '3', '4', '6', '7', '8', '9'];
var fullarray;
var generator = function() {
  fullarray = [];
  var numgen;
  // first digit
  for (var a = 7; a >= 0; a--) {
    var anum = listofavailable[a];
    listofavailable.splice(a, 1);
    numgen = anum;
    // second digit
    for (var i = 6; i >= 0; i--) {
      var inum = listofavailable[i];
      listofavailable.splice(i, 1);
      numgen = numgen.concat(inum);
      // third digit
      for (var v = 5; v >= 0; v--) {
        var vnum = listofavailable[v];
        listofavailable.splice(v, 1);
        numgen = numgen.concat(vnum);
        // fourth digit
        for (var c = 4; c >= 0; c--) {
          var cnum = listofavailable[c];
          listofavailable.splice(c, 1);
          numgen = numgen.concat(cnum);
          // fifth digit
          for (var g = 3; g >= 0; g--) {
            var gnum = listofavailable[g];
            listofavailable.splice(g, 1);
            numgen = numgen.concat(gnum);
            // sixth digit
            for (var k = 2; k >= 0; k--) {
              var knum = listofavailable[k];
              listofavailable.splice(k, 1);
              numgen = numgen.concat(knum);
              // seventh digit
              for (var b = 1; b >= 0; b--) {
                var bnum = listofavailable[b];
                listofavailable.splice(b, 1);
                numgen = numgen.concat(bnum);
                // eighth digit
                //add whatever else is left in listofavailable[0] to the string
                var jnum = listofavailable[0];
                numgen = numgen.concat(jnum);
                fullarray.push(numgen);
                //console.log(numgen);
                //revert list removals
                listofavailable.push(numgen.substr(numgen.length - 2,1));
                //revert additions to the string
                numgen = numgen.substr(0,numgen.length-2);
              }// b loop
              listofavailable.push(numgen.substr(numgen.length - 1));
              numgen = numgen.substr(0,numgen.length-1);
            }// k loop
            listofavailable.push(numgen.substr(numgen.length - 1));
            numgen = numgen.substr(0,numgen.length-1);
          }// g loop
          listofavailable.push(numgen.substr(numgen.length - 1));
          numgen = numgen.substr(0,numgen.length-1);
        }// c loop
        listofavailable.push(numgen.substr(numgen.length - 1));
        numgen = numgen.substr(0,numgen.length-1);
      }// v loop
      listofavailable.push(numgen.substr(numgen.length - 1));
      numgen = numgen.substr(0,numgen.length-1);
    } // i loop
    listofavailable.push(numgen.substr(numgen));
    numgen = "";
  } // a loop
};
generator();
console.log(fullarray.length);
console.log(fullarray);

解释原始代码出了什么问题。

您在 b 循环的第二次迭代中得到一个未定义

              bnum = listofavailable[b];

这是因为您的函数每次拼接一个值时都会清空 7 个可用值的数组,listofavailable作为单个元素数组,listofavailable[0] = "1" . 但是,当 b 第二次迭代时,它试图获取不存在的元素listofavailable[1],因此bnum = undefined . 当尝试将undefined值连接到numgen时,这会numgen = undefined并在之后破坏所有内容。

此外,您尝试添加到数组的方式

fullarray = fullarray + numgen;

没有按照您的意图执行,您实际上是在寻找 Array.prototype.push() 函数,所以它会是

fullarray.push(numgen);

对 listofavailable 使用重置值是个好主意,但你实现它的方式也不会像

listofavailable = listofavailablereset;

不会将数组元素从listofavailablereset复制到listofavailable,但它只是使listofavailable引用相同的数组对象,因此当您修改一个时,您会影响另一个。相反,您可以使用slice()复制数组。

listofavailable = listofavailablereset.slice();

请注意,slice()只创建一个浅拷贝,每个数组中的对象引用都将指向同一个对象。

查看 Mozilla Javascript 参考页面,了解优秀的 JavaScript 参考文档。

通过生成这些排列所做的与枚举所有以 8 位为数的 8 位数字同构,所以只需这样做:

var digits = ['1', '2', '3', '4', '6', '7', '8', '9'];
var n, d, permutations = [], entry;
for (var i = 0, limit = parseInt("100000000", 8); i < limit; ++i) {
  entry = "";
  for (d = 0, n = i; d < digits.length; ++d) {
    entry = digits[n % 8] + entry;
    n = Math.floor(n / 8);
  }
  permutations.push(entry);
}
console.log(permutations);

请注意,这将需要很长时间。您的浏览器(如果您在浏览器中执行此操作)会抱怨脚本繁忙。