最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

shifting arrays in a for loop in JavaScript - Stack Overflow

programmeradmin9浏览0评论

Sometimes the simplest things bee the most confusing.

let arr = ['x', 'y', 'z'];

for(let i = 0; i <= arr.length; i++) {
    let prop = arr.shift();
    console.log(prop); 
    console.log(arr, `${i} <= ${arr.length}`);
}

Sometimes the simplest things bee the most confusing.

let arr = ['x', 'y', 'z'];

for(let i = 0; i <= arr.length; i++) {
    let prop = arr.shift();
    console.log(prop); 
    console.log(arr, `${i} <= ${arr.length}`);
}

it prints out

x
[ 'y', 'z' ] '0 <= 2'
y
[ 'z' ] '1 <= 1'

How e 'z' doesn't show up with this code as part of the console.log(prop)?

Share Improve this question asked Mar 6, 2019 at 16:12 totalnoobtotalnoob 2,74110 gold badges39 silver badges72 bronze badges 3
  • Because you're adjusting the length of the array with every shift. – Scott Sauyet Commented Mar 6, 2019 at 16:18
  • by z, shouldn't the length be 1 with i being 1, 1 <= 1? – totalnoob Commented Mar 6, 2019 at 16:19
  • But by then i is 2. – Scott Sauyet Commented Mar 6, 2019 at 16:25
Add a ment  | 

6 Answers 6

Reset to default 4

You short the array by shifting and use an index with is incrementing for every loop.

The result is it loops only twice, one for element one and two, and one for element three.

At the end, you got index 2, but the length of the array is 1.

let arr = ['x', 'y', 'z'];

for(let i = 0; i <= arr.length; i++) {
    let prop = arr.shift();
    console.log(prop); 
    console.log(arr, `${i} <= ${arr.length}`);
}

A better approach by using only the shiftend element and checking only the length of the array.

let arr = ['x', 'y', 'z'],
    i = 0;

while (arr.length) {
    let prop = arr.shift();
    console.log(prop); 
    console.log(arr, `${++i} < ${arr.length}`);
}

You adjust the length of the array with every shift call, and the boundary check inside your for-loop tests against that.

You can cache the length in another variable to demonstrate:

let arr = ['x', 'y', 'z'];
let len = arr.length;

for(let i = 0; i < len; i++) {
    let prop = arr.shift();
    console.log(prop); 
    console.log(arr, `${i} <= ${arr.length}`);
}

This technique was once remended by some for performance reasons; that is rarely necessary any more. But if your loop is changing the array, it might still be important.


Why this doesn't work as is:

  1. set arr to ['x', 'y', 'z']
  2. set i to 0
  3. test i <= arr.length, true since 0 <= 3
  4. do loop body, prop is 'x', arr is ['y', 'z']
  5. perform i++, now i is 1
  6. test i < arr.length, true since 1 <= 2
  7. do loop body, prop is 'y', arr is ['z']
  8. perform i++, now i is 2
  9. test i < arr.length, false since 2 > 1
  10. pleted

This is because at the end of the second loop, the array is ['z'], i is 1, and arr.length is 1 as well. However, before the next iteration, i is incremented to 2 which is greater than arr.length = 1, which effectively stops the loop.

Array.prototype.shift mutates an array by both removing the first element and decreasing its length property.

Therefore, before you get to the 3rd element (z), arr's length is 1. However, i is 2. Your for loop exits because 2 > 1; thus, you don't see z logged to the console.

Your changing the length every time you do an array shift

let arr = ['x', 'y', 'z'];

for (let i = 0; i <= 2; i++) {
  let prop = arr.shift();
  console.log(prop);
  console.log(arr, `${i} <= ${arr.length}`);
}

z is not getting printed because the value of i bees greater then the length of array when it reaches z, which is 1. the loop wont run further as i<array.length is violated. i will be 2 and length will be 1

You can use a while loop like this

let arr = ['x', 'y', 'z'];
let i=0;
var x=arr.length;
while(i<x) {
    let prop = arr.shift();
    console.log(prop); 
    if(i<=arr.length)
    console.log(arr, `${i} <= ${arr.length}`);
    i++;
}

发布评论

评论列表(0)

  1. 暂无评论