Reputation: 21
I have this array :
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
and I want to remove array value sequentially from first index. so it will produce:
[ "apple", "orange", "watermelon", "blueberry", "lemon", "guava" ]
[ "orange", "watermelon", "blueberry", "lemon", "guava" ]
[ "watermelon", "blueberry", "lemon", "guava" ]
[ "blueberry", "lemon", "guava" ]
[ "lemon", "guava" ]
[ "guava" ]
I've already tried this code:
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
runLoop = async () => {
for(const item of items){
await new Promise( resolve => setTimeout( resolve, 1000 ));
console.log(items);
remove(items, item);
console.log('------------');
}
}
function remove(array, element) {
console.log('deleting '+element);
const index = array.indexOf(element);
array.splice(index, 1);
}
but the result it's not what I expected, here is the result:
Array(6) [ "apple", "orange", "watermelon", "blueberry", "lemon", "guava" ]
Array(5) [ "orange", "watermelon", "blueberry", "lemon", "guava" ]
Array(4) [ "orange", "blueberry", "lemon", "guava" ]
Upvotes: 1
Views: 56
Reputation: 370659
The problem is that array iterable is live - if you invoke the iterator with for..of
and mutate the array while that iterator is still being used, the resulting items iterated over will likely be unintuitive - some indicies may be missed. It's kind of like what's going on here:
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
for (let i = 0; i < items.length; i++) {
console.log('item: ', items[i]);
items.splice(i, 1);
}
The loop only runs 3 times, because you're removing items from the array while you're iterating over it, so some indicies get skipped.
One possibility is to make a copy of the array first, when invoking the iterator with for..of
, so that the iterator will always iterate over every item that was in the original array sequentially:
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
runLoop = async () => {
for(const item of items.slice()){
await new Promise( resolve => setTimeout( resolve, 300 ));
console.log(items);
remove(items, item);
console.log('------------');
}
}
function remove(array, element) {
console.log('deleting '+element);
const index = array.indexOf(element);
array.splice(index, 1);
}
runLoop();
Upvotes: 3
Reputation: 101
You can use Array.slice to achieve this. When using splice, remember that it will affect the original array, which should not be done according to the functional approach of javascript. Functional programming doesn't recommend to mutate the original object.
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
for(let i=0;i<items.length;i++){
console.log(items.slice(i,items.length));
}
Upvotes: 0
Reputation: 50291
An alternative can a recursive function and shift which removes the first element from an array
let items = ["apple", "orange", "watermelon", "blueberry", "lemon", "guava"];
function removeElem(arr) {
if (arr.length !== 1) {
console.log(arr)
arr.shift();
removeElem(arr)
} else {
console.log(arr)
}
}
removeElem(items)
Upvotes: 0
Reputation: 386540
You need to splice at index zero,
array.splice(0, 1);
or just shift the first element.
array.shift();
Upvotes: 1