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
Ruby - Elegantly Convert Variable to an Array If Not an Array Already
Parse Command Line Arguments in a Ruby Script
How to Handle Constants in Ruby When Using Rails
What's the Difference Between Request.Remote_Ip and Request.Ip in Rails
Installed Rails But the Rails Command Says It's Not Installed
Rails Authentication Across Apps/Servers
When to Use Struct Instead of Hash in Ruby
Installing Ruby 1.9.1 on Ubuntu
Ruby: Is There an Opposite of Include? for Ruby Arrays
Ruby: How to Concatenate Array of Arrays into One
Install Latest Stable Version of Ruby Using Rbenv
Why Do I Need to Work Harder to Make My Rails Application Fit into a Restful Architecture
If String Is Empty Then Return Some Default Value
Vagrant/Virtualbox Vm Provisioning: Rbenv Installs Successfully But Subsequent Uses in Script Fail