简体   繁体   English

javascript while循环正确迭代但是对于具有相同逻辑的循环不是,在具有整数值的数组和那里的一些空值

[英]javascript while loop correctly iterating but for loop with same logic is not, on array with integer values and some null values in there

Iterating through a javascript array which has some data in, and some null or not defined values also, is giving funny behaviors with a for loop, but not with a while loop. 迭代通过一个javascript数组,其中包含一些数据,以及一些nullnot defined值,使用for循环给出有趣的行为,但不使用while循环。 It is not returning when it should and is stuck in an infinite loop 它不应该返回它应该并且陷入无限循环

I have investigated the outputs extensively, the condition whether the number exists in the array is never evaluated to be true , only ever false , but it sometimes enters the if statement region as if it is true. 我已经广泛地调查了输出,数组中是否存在数字的条件永远不会被评估为true ,只是false ,但它有时会进入if语句区域,就好像它是真的一样。 It is seemingly arbitrary. 这似乎是武断的。

//function called within this code

function randomArrayOfIndexes() {
    var randNumbArray = new Array(4);
    var indexToAssign = Math.floor(Math.random() * Math.floor(4));
    randNumbArray[0] = indexToAssign;


for (i = 1; i < randNumbArray.length; i++) {
    indexToAssign = Math.floor(Math.random() * Math.floor(4));
    while (arrayContains(randNumbArray, indexToAssign)) {
        indexToAssign = Math.floor(Math.random() * Math.floor(4));
    }
    randNumbArray[i] = indexToAssign;
}

return randNumbArray;
}

//this works

function arrayContains(arrayin, numberIn) {
    var i = arrayin.length;
    while (i--) { //takes one from i so highest index is accurate on first iteration
        if (arrayin[i] === numberIn) {
            return true;
        }
    }
    return false;
}

//this doesn't... not even backwards like the above iteration

function arrayIncludes(arrayin, numberIn) {
    for (i = 0; i < arrayin.length; i++) {
        if (arrayin[i] === numberIn) {
            return true;
        }
    }
    return false;

}

At first each function above is passed in an array with [int value, null, null, null], and a random number; 首先,上面的每个函数都在一个数组中传递,其中包含[int value,null,null,null]和一个随机数; when the function returns, the next null value is filled with the random number that doesn't exist in it already, so [int value, int value, null, null]... until all values are filled... the final array is filled with unique random numbers from 0 to 3, to provide an index for a piece of data in another array... to make sure that it is only used once in the program I am writing. 当函数返回时,下一个空值用已经不存在的随机数填充,所以[int value,int value,null,null] ...直到所有值都被填充...最后一个数组填充了从0到3的唯一随机数,为另一个数组中的一段数据提供索引...以确保它只在我正在编写的程序中使用一次。

I would expect it to return true if the number passed in is already in there, another random number then generated outside of the broken function, and the process repeated until a unique random number is found. 如果传入的数字已经在那里,我希望它返回true,然后在破坏的函数之外生成另一个随机数,并且重复该过程直到找到唯一的随机数。 When it is found, the array being passed back in will be populated at the next available index, and the process repeated. 找到后,传回的数组将填入下一个可用索引,并重复该过程。 This is not happening. 这不会发生。 It is getting stuck in an infinite loop, and never returning 它陷入无限循环,永不回归

you are just missing a var before i : 你之前i错过了一个var

function arrayIncludes(arrayin, numberIn) {
    for (var i = 0; i < arrayin.length; i++) {
//     in ^ here
        if (arrayin[i] === numberIn) {
            return true;
        }
    }
    return false;

}

You may also declare it before loop, like 你也可以在循环之前声明它,比如

var i;
for (i = 0; i < arrayin.length; i++) {
...

By the way, this way of generating random numbers without duplicates is very inefficient, I suggest something like having an array of 0-3 (in your current example) or 0-n and then just randomly taking items out of it. 顺便说一下,这种生成随机数而没有重复的方法是非常低效的,我建议使用0-3(在当前示例中)或0-n的数组,然后随机地从中取出项目。 then you don't have to loop through the whole array each time you find a new number. 那么每次找到新数字时都不必遍历整个数组。 every time you just find a random index between 0 and the length of remaining items. 每次你只是找到0和剩余项目长度之间的随机索引。

Imagine that the array length is 1000, and the last item remaining is a number like 100, how many times you have to find a random number and loop through whole array till your random number is 100? 想象一下,数组长度是1000,剩下的最后一项是100这样的数字,你需要多少次找到一个随机数并遍历整个数组,直到你的随机数为100?

 var n = 5; var a = new Array(n); for(var i=0;i<n;i++) a[i] = i; var result = new Array(n); var i = n; while(i) { var index = Math.floor(Math.random() * i); result[--i] = a[index]; a.splice(index,1); } document.getElementById('a').innerHTML = result; 
 <div id="a"></div> 

You need to declare variables in you loops with for i=0 . 你需要在for i=0循环中声明变量for i=0 if you don't do this the variable is global and when you use the same loop variable in nested loops one can change the other. 如果你不这样做,变量是全局的,当你在嵌套循环中使用相同的循环变量时,可以改变另一个变量。

You are using i in both loops so when you call the for loop with: 你在两个循环中使用i所以当你用以下方法调用for循环时:

function arrayIncludes(arrayin, numberIn) {
    for (i = 0; i < arrayin.length; i++) {
 // etc 
 }

You set i back to 0 ad iterate it — this is the same i you are using in randomArrayOfIndexes so it interferes with that loop. 您可以设置i回到0广告遍历它-这是 i使用的是在randomArrayOfIndexes因此它与环干扰。 This is a common cause of hard-to-find bugs and is hy you should always declare loop variables. 这是难以发现的错误的常见原因,你应该总是声明循环变量。

Here's the bug in it's simplest form. 这是最简单形式的错误。 Notice that the out loop only runs once because i is incremented in the inner loop causing the outloop to exit early: 请注意,out循环只运行一次,因为i在内循环中递增,导致outloop提前退出:

 for (i = 0; i < 4; i++){ console.log("out loop number: ", i) for (i = 0; i < 4; i++){ console.log("inner_loop: ", i) } } 

If you declare the variables for for let i = , each loop gets its own version of i both loops run independently: 如果for let i =声明变量,则每个循环都有自己的i版本,两个循环独立运行:

 for (let i = 0; i < 4; i++){ console.log("out loop number: ", i) for (let i = 0; i < 4; i++){ console.log("inner_loop: ", i) } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM