How to Use Array#Delete While Iterating Over the Array

How can I use Array#delete while iterating over the array?

a.delete_if { |x| x >= 3 }

See method documentation here

Update:

You can handle x in the block:

a.delete_if do |element|
if element >= 3
do_something_with(element)
true # Make sure the if statement returns true, so it gets marked for deletion
end
end

Looping through array and removing items, without breaking for loop

The array is being re-indexed when you do a .splice(), which means you'll skip over an index when one is removed, and your cached .length is obsolete.

To fix it, you'd either need to decrement i after a .splice(), or simply iterate in reverse...

var i = Auction.auctions.length
while (i--) {
...
if (...) {
Auction.auctions.splice(i, 1);
}
}

This way the re-indexing doesn't affect the next item in the iteration, since the indexing affects only the items from the current point to the end of the Array, and the next item in the iteration is lower than the current point.

Is it supposed to be safe to remove elements from an array while iterating with for..of in JavaScript?

No, (as your example demonstrates) it's not safe to remove elements from an array while iterating it.

The default array iterator stores the current index, and it does not update this index when you call splice on the array. It just continues at the same position, no matter what you did to the elements in the array. You can read the spec for ArrayIterator objects, they basically work like a for (var index=0; index<array.length; index++) yield array[index]; loop.

Delete element of array while iterating

It's because of the index of the deleted element. I added some output to show you:

arr = [1,2,3]  
arr.each do |x|
puts "1: #{arr.inspect}, x: #{x}"
arr.each do |y|
puts "2: #{arr.inspect}, y: #{y}"
puts "#{arr.delete(y)}"
end
end

Result:

1: [1, 2, 3], x: 1
2: [1, 2, 3], y: 1
1
2: [2, 3], y: 3
3
=> [2]

The first deleted element is 1 (index is 0) in the inner each block. After the deletion 2 has the index 0 and now the each iteration goes to index 1 which is now element 3. 3 will be deleted and that's the end of the iteration. So you get [2].

The same happens without nested each:

arr = [1,2,3]  
arr.each do |x|
puts "1: #{arr.inspect}, x: #{x}"
puts "#{arr.delete(x)}"
end

Result:

1: [1, 2, 3], x: 1
1
1: [2, 3], x: 3
3
=> [2]

I suggest to use reverse_each for such operations to avoid this behavior:

arr = [1,2,3]  
arr.reverse_each do |x|
puts "1: #{arr.inspect}, x: #{x}"
puts "#{arr.delete(x)}"
end

Result:

1: [1, 2, 3], x: 3
3
1: [1, 2], x: 2
2
1: [1], x: 1
1
=> []

How to iterate over an array and remove elements in JavaScript

Start from the top!

var elements = [1, 5, 5, 3, 5, 2, 4];
for(var i = elements.length - 1; i >= 0; i--){
if(elements[i] == 5){
elements.splice(i, 1);
}
}

Removing elements from an array while iterating in while loop

i is never initialized nor updated, so the while loop doesn't make too much sense.
You can try this instead:

let nameArray = ['Chara','Lisette','Corine','Kevin','Carlee'];
while(nameArray.length > 0) { // while the array is not empty
let i = Math.floor(Math.random() * nameArray.length); // pick a random element index
console.log(nameArray[i]); // print the element
nameArray.splice(i, 1); // remove the element from the array
}

Remove array item using for...of loop

You can't reasonably use for-of for this. If you remove the "current" entry during the iteration, you'll skip the next entry, because of the way array iterators are specified (they use the index of the entry). You can see that with this contrived example:

const array = [1, 2, 3];for (const entry of array) {    console.log(entry);    if (entry === 2) {        array.splice(1, 1);    }}console.log(array);

How to remove items from a list while iterating?

You can use a list comprehension to create a new list containing only the elements you don't want to remove:

somelist = [x for x in somelist if not determine(x)]

Or, by assigning to the slice somelist[:], you can mutate the existing list to contain only the items you want:

somelist[:] = [x for x in somelist if not determine(x)]

This approach could be useful if there are other references to somelist that need to reflect the changes.

Instead of a comprehension, you could also use itertools. In Python 2:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

Or in Python 3:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

Is it safe to delete from an Array inside each?

You should not rely on unauthorized answers too much. The answer you cited is wrong, as is pointed out by Kevin's comment to it.

It is safe (from the beginning of Ruby) to delete elements from an Array while each in the sense that Ruby will not raise an error for doing that, and will give a decisive (i.e., not random) result.

However, you need to be careful because when you delete an element, the elements following it will be shifted, hence the element that was supposed to be iterated next would be moved to the position of the deleted element, which has been iterated over already, and will be skipped.

How to remove an element from an array while iterating in Ballerina

I don't think there is a direct way to do this in Ballerina. I would suggest to use lang.array:filter method and create a new array excluding the members you wish to remove.

    int[] ar = [1, 2, 3, 4];
int[] filtered = ar.filter(i => i != 2);


Related Topics



Leave a reply



Submit