[英]When many for loops are used in Javascript, output is undefined
As shown at https://jsfiddle.net/LBMF_1/gacLzLnn/ , I have code that ostensibly generates all the possible permutations of 8 digits, using for loops within for loops.( At end of question ) My code seems to be correct in syntax, as both JSHint and the in-chrome console are free of errors. 如https://jsfiddle.net/LBMF_1/gacLzLnn/所示,我的代码表面上使用for循环中的for循环,表面上生成了8位数字的所有可能排列。( 问题末尾 )我的代码似乎是正确的语法,因为JSHint和in-chrome控制台都没有错误。 Is this my error, or is this a common problem caused by JS?
这是我的错误,还是由JS引起的常见问题? It's probably the former as it seems that this should work Bonus Points: What other ways could be used to avoid the nested for loops?
可能应该是前者,因为这似乎应该起作用奖励积分:可以使用其他什么方法来避免嵌套的for循环? You don't know how much I am thankful for any help.
您不知道我有多感谢您的帮助。 Also, what is up with Stack Overflow and new paragraphs?
此外,Stack Overflow和新段落的内容如何? The code is here, and it appears to me that when run should stick a really long list of numbers in the console, but instead lots of "undefined"'s appear.
代码在这里,在我看来,运行时应该在控制台中粘贴一长串数字,但会出现许多“未定义”的数字。
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;
}
}
}
}
}
}
}
};
Here's a modified implementation based on your fiddle. 这是根据您的小提琴修改的实现。 Note that the digits '0' and '5' are missing from your example, I'm not sure if this is intended.
请注意,您的示例中缺少数字“ 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);
To explain what was wrong with the original code. 解释原始代码出了什么问题。
You are getting an undefined on the second iteration of the b loop 您在b循环的第二次迭代中得到的是未定义的
bnum = listofavailable[b];
this is because your function was emptying out the array of 7 available values, each time it splices out a value, leaving listofavailable
as a single element array, listofavailable[0] = "1"
. 这是因为您的函数在每次拼接一个值时都会清空7个可用值的数组,将
listofavailable
为单个元素数组, listofavailable[0] = "1"
。 However, when b iterates the second time it is trying to get the element listofavailable[1]
which doesn't exist, hence bnum = undefined
. 但是,当b第二次迭代时,它将尝试获取不存在的元素
listofavailable[1]
,因此bnum = undefined
。 When trying to concatenate the undefined
value to numgen
this then makes numgen = undefined
and breaks everything afterwards. 当尝试将
undefined
值连接到numgen
这将使numgen = undefined
并随后破坏所有内容。
Additionally, the way you're trying to add to an array 此外,您尝试添加到数组的方式
fullarray = fullarray + numgen;
doesn't perform how you're intending, you're actually looking for the Array.prototype.push() function, so it would be 不会执行您的预期,实际上是在寻找Array.prototype.push()函数,因此
fullarray.push(numgen);
and using a reset value for the listofavailable is a good idea, but the way you've implemented it also won't work as 并为listofavailable使用重置值是个好主意,但是您实现它的方式也无法
listofavailable = listofavailablereset;
doesn't copy the array elements from listofavailablereset
into listofavailable
but it just makes listofavailable
reference the same array object, hence when you modify one, you're affecting the other. 不会将数组元素从
listofavailablereset
复制到listofavailable
而是使listofavailable
引用同一数组对象,因此,当您修改一个数组对象时,会影响另一个数组对象。 Instead you can just copy your array over using slice()
eg. 相反,您可以仅使用
slice()
复制数组。
listofavailable = listofavailablereset.slice();
Note that slice()
only creates a shallow copy, object references within each array will both point to the same object. 请注意,
slice()
仅创建一个浅表副本,每个数组中的对象引用都将指向同一对象。
Check out the Mozilla Javascript Reference pages for excellent javascript reference documentation. 请查看Mozilla Javascript参考页面,以获得出色的JavaScript参考文档。
What you're doing by generating these permutations is isomorphic to enumerating all of the 8-digit base 8 numbers, so just do that: 通过生成这些排列,您所做的工作与枚举所有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);
Note that this will take a long time. 请注意,这将花费很长时间。 Your browser (if you're doing it in a browser) will complain about a busy script.
您的浏览器(如果您正在浏览器中进行操作)将抱怨脚本繁忙。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.