sgtoka
sgtoka

Reputation: 21

removing array javascript value sequentially from first index

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

Answers (4)

CertainPerformance
CertainPerformance

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

Samudra Deka
Samudra Deka

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

brk
brk

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

Nina Scholz
Nina Scholz

Reputation: 386540

You need to splice at index zero,

array.splice(0, 1);

or just shift the first element.

array.shift();

Upvotes: 1

Related Questions