Looping through array and removing items, without breaking for loop
up vote
366
down vote
favorite
I have the following for loop, and when I use splice()
to remove an item, I then get that 'seconds' is undefined. I could check if it's undefined, but I feel there's probably a more elegant way to do this. The desire is to simply delete an item and keep on going.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
javascript loops
add a comment |
up vote
366
down vote
favorite
I have the following for loop, and when I use splice()
to remove an item, I then get that 'seconds' is undefined. I could check if it's undefined, but I feel there's probably a more elegant way to do this. The desire is to simply delete an item and keep on going.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
javascript loops
7
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09
add a comment |
up vote
366
down vote
favorite
up vote
366
down vote
favorite
I have the following for loop, and when I use splice()
to remove an item, I then get that 'seconds' is undefined. I could check if it's undefined, but I feel there's probably a more elegant way to do this. The desire is to simply delete an item and keep on going.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
javascript loops
I have the following for loop, and when I use splice()
to remove an item, I then get that 'seconds' is undefined. I could check if it's undefined, but I feel there's probably a more elegant way to do this. The desire is to simply delete an item and keep on going.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
javascript loops
javascript loops
edited Sep 19 '16 at 19:08
JJJ
29k147591
29k147591
asked Mar 27 '12 at 1:44
dzm
8,90935102185
8,90935102185
7
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09
add a comment |
7
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09
7
7
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09
add a comment |
12 Answers
12
active
oldest
votes
up vote
712
down vote
accepted
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.
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
|
show 12 more comments
up vote
101
down vote
This is a pretty common issue. The solution is to loop backwards:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards.
add a comment |
up vote
36
down vote
Recalculate the length each time through the loop instead of just at the outset, e.g.:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
That way you won't exceed the bounds.
EDIT: added a decrement in the if statement.
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
add a comment |
up vote
20
down vote
Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation.
The algorithmic complexity of this approach is O(n^2)
as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon).
var newArray = ;
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
Since ES2015 we can use Array.prototype.filter
to fit it all in one line:
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use theArray.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on usingfilter
vs. iterating backwards +splice
?
– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
|
show 3 more comments
up vote
16
down vote
Auction.auction = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
add a comment |
up vote
9
down vote
Here is another example for the proper use of splice. This example is about to remove 'attribute' from 'array'.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not becausei--
reduces the index. If you doarray.length-1
then the last element ofarray
will be skipped
– daniel.szaniszlo
Nov 15 '17 at 0:23
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrementi
.for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)
– Izzy
Nov 15 '17 at 11:53
add a comment |
up vote
8
down vote
Another simple solution to digest an array elements once:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
add a comment |
up vote
3
down vote
If you are e using ES6+ - why not just use Array.filter method?
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
Note that modifying the array element during filter iteration only works for objects and will not work for array of primitive values.
add a comment |
up vote
1
down vote
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
add a comment |
up vote
0
down vote
Try to relay an array into newArray when looping:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = ;
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
add a comment |
up vote
0
down vote
You can just look through and use shift()
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
add a comment |
up vote
0
down vote
There are lot of wonderful answers on this thread already. However I wanted to share my experience when I tried to solve "remove nth element from array" in ES5 context.
JavaScript arrays have different methods to add/remove elements from start or end. These are:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Essentially none of the above methods can be used directly to remove nth element from the array.
A fact worth noting is that this is in contrast with java iterator's
using which it is possible to remove nth element for a collection
while iterating.
This essentially leaves us with only one array method Array.splice
to perform removal of nth element (there are other things you could do with these methods as well, but in the context of this question I am focusing on removal of elements):
Array.splice(index,1) - removes the element at the index
Here is the code copied from original answer (with comments):
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
Another noteworthy method is Array.slice
. However the return type of this method is the removed elements. Also this doesn't modify original array. Modified code snippet as follows:
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
Having said that, we can still use Array.slice
to remove nth element in the following way and as you can observe it is lot more code (hence inefficient)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
The
Array.slice
method is extremely important to achieve
immutability in functional programming à la redux
add a comment |
12 Answers
12
active
oldest
votes
12 Answers
12
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
712
down vote
accepted
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.
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
|
show 12 more comments
up vote
712
down vote
accepted
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.
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
|
show 12 more comments
up vote
712
down vote
accepted
up vote
712
down vote
accepted
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.
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.
edited Dec 8 '17 at 17:03
community wiki
4 revs, 3 users 76%
user1106925
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
|
show 12 more comments
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
1
1
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
Looks like the best solution to me. And the fastest one, by the way.
– Dmitry Pashkevich
Oct 25 '12 at 13:08
1
1
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
Nice! Why is this a community wiki btw?
– 0xc0de
Sep 6 '13 at 7:10
10
10
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
When you remove an entry from the array, then the next item you'll iterate over will be the same item as you are currently iteration over. Just something to keep in mind. And if you remove more than one item per iteration, you'll have to adjust len, else it will be out of bounds.
– ptf
Dec 10 '14 at 9:42
2
2
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
Pro tip: Never forget this solution
– super
Jun 6 '16 at 18:39
1
1
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
@squint Oh, I see. the condition i-- will at some point return 0, and 0 will be evaluated to false. Neat.
– frattaro
Apr 2 '17 at 13:27
|
show 12 more comments
up vote
101
down vote
This is a pretty common issue. The solution is to loop backwards:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards.
add a comment |
up vote
101
down vote
This is a pretty common issue. The solution is to loop backwards:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards.
add a comment |
up vote
101
down vote
up vote
101
down vote
This is a pretty common issue. The solution is to loop backwards:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards.
This is a pretty common issue. The solution is to loop backwards:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
It doesn't matter if you're popping them off of the end because the indices will be preserved as you go backwards.
answered Jan 24 '15 at 3:49
frattaro
1,5641108
1,5641108
add a comment |
add a comment |
up vote
36
down vote
Recalculate the length each time through the loop instead of just at the outset, e.g.:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
That way you won't exceed the bounds.
EDIT: added a decrement in the if statement.
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
add a comment |
up vote
36
down vote
Recalculate the length each time through the loop instead of just at the outset, e.g.:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
That way you won't exceed the bounds.
EDIT: added a decrement in the if statement.
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
add a comment |
up vote
36
down vote
up vote
36
down vote
Recalculate the length each time through the loop instead of just at the outset, e.g.:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
That way you won't exceed the bounds.
EDIT: added a decrement in the if statement.
Recalculate the length each time through the loop instead of just at the outset, e.g.:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
That way you won't exceed the bounds.
EDIT: added a decrement in the if statement.
answered Mar 27 '12 at 1:50
Marc
7,76712633
7,76712633
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
add a comment |
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
8
8
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
I thnk it's easier to just go backwards through the array, then you don't need to adjust the length at all.
– RobG
Mar 27 '12 at 2:08
4
4
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
I also overlooked recalculating the array length after splicing in a loop. Funny how something so simple can have us scratching our heads for a moment.
– Doug S
Oct 27 '12 at 5:40
add a comment |
up vote
20
down vote
Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation.
The algorithmic complexity of this approach is O(n^2)
as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon).
var newArray = ;
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
Since ES2015 we can use Array.prototype.filter
to fit it all in one line:
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use theArray.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on usingfilter
vs. iterating backwards +splice
?
– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
|
show 3 more comments
up vote
20
down vote
Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation.
The algorithmic complexity of this approach is O(n^2)
as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon).
var newArray = ;
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
Since ES2015 we can use Array.prototype.filter
to fit it all in one line:
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use theArray.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on usingfilter
vs. iterating backwards +splice
?
– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
|
show 3 more comments
up vote
20
down vote
up vote
20
down vote
Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation.
The algorithmic complexity of this approach is O(n^2)
as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon).
var newArray = ;
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
Since ES2015 we can use Array.prototype.filter
to fit it all in one line:
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
Although your question is about deleting elements from the array being iterated upon and not about removing elements (in addition to some other processing) efficiently, I think one should reconsider it if in similar situation.
The algorithmic complexity of this approach is O(n^2)
as splice function and the for loop both iterate over the array (splice function shifts all elements of array in the worst case). Instead you can just push the required elements to the new array and then just assign that array to the desired variable (which was just iterated upon).
var newArray = ;
for (var i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
auction.seconds--;
if (!auction.seconds < 0) {
newArray.push(auction);
}
}
Auction.auctions = newArray;
Since ES2015 we can use Array.prototype.filter
to fit it all in one line:
Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);
edited Sep 26 at 16:28
dhilt
7,36921839
7,36921839
answered Sep 6 '13 at 8:01
0xc0de
4,39023363
4,39023363
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use theArray.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on usingfilter
vs. iterating backwards +splice
?
– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
|
show 3 more comments
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use theArray.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on usingfilter
vs. iterating backwards +splice
?
– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
2
2
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use the
Array.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…– Alexis Wilke
May 24 '14 at 4:55
I thinks your method is the safest, as it creates a new array we do not have to worry about the for() index to "break". With newer browsers, though we can use the
Array.filter()
function instead: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…– Alexis Wilke
May 24 '14 at 4:55
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
note that the filter version here doesn't decrement the seconds on every auction like the for loop version!
– user1115652
Jan 4 '15 at 20:44
Does anyone have a benchmark on using
filter
vs. iterating backwards + splice
?– qxz
Nov 24 '16 at 3:51
Does anyone have a benchmark on using
filter
vs. iterating backwards + splice
?– qxz
Nov 24 '16 at 3:51
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
Filter works for me.
– emanuel.virca
Apr 6 '17 at 14:38
2
2
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
Updated to use an arrow: auctions = auctions.filter(auction => --auction.seconds >=0) now whole thing fits on one line and the browser compatibility is good in 2017.
– whitneyland
Dec 1 '17 at 11:52
|
show 3 more comments
up vote
16
down vote
Auction.auction = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
add a comment |
up vote
16
down vote
Auction.auction = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
add a comment |
up vote
16
down vote
up vote
16
down vote
Auction.auction = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
Auction.auction = Auction.auctions.filter(function(el) {
return --el["seconds"] > 0;
});
answered Sep 6 '13 at 8:12
Aesthete
14.9k42338
14.9k42338
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
add a comment |
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
This is a cool method, similar to 0xc0de above. Only problem, it was implemented in IE9+ only... so not backward compatible.
– Alexis Wilke
May 24 '14 at 4:17
9
9
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
@AlexisWilke: Luckily, we're in the future now, and can dance on the graves of IE8 and its predecessors.
– Michael Scheper
Dec 13 '16 at 3:48
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
I think the main issue is it breaks the reference to the array.
– Arashsoft
Nov 14 at 21:09
add a comment |
up vote
9
down vote
Here is another example for the proper use of splice. This example is about to remove 'attribute' from 'array'.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not becausei--
reduces the index. If you doarray.length-1
then the last element ofarray
will be skipped
– daniel.szaniszlo
Nov 15 '17 at 0:23
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrementi
.for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)
– Izzy
Nov 15 '17 at 11:53
add a comment |
up vote
9
down vote
Here is another example for the proper use of splice. This example is about to remove 'attribute' from 'array'.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not becausei--
reduces the index. If you doarray.length-1
then the last element ofarray
will be skipped
– daniel.szaniszlo
Nov 15 '17 at 0:23
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrementi
.for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)
– Izzy
Nov 15 '17 at 11:53
add a comment |
up vote
9
down vote
up vote
9
down vote
Here is another example for the proper use of splice. This example is about to remove 'attribute' from 'array'.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
Here is another example for the proper use of splice. This example is about to remove 'attribute' from 'array'.
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
answered Feb 26 '16 at 12:34
daniel.szaniszlo
16116
16116
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not becausei--
reduces the index. If you doarray.length-1
then the last element ofarray
will be skipped
– daniel.szaniszlo
Nov 15 '17 at 0:23
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrementi
.for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)
– Izzy
Nov 15 '17 at 11:53
add a comment |
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not becausei--
reduces the index. If you doarray.length-1
then the last element ofarray
will be skipped
– daniel.szaniszlo
Nov 15 '17 at 0:23
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrementi
.for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)
– Izzy
Nov 15 '17 at 11:53
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
shouldn't be that array.length-1 ?
– Izzy
Nov 13 '17 at 10:49
I think not because
i--
reduces the index. If you do array.length-1
then the last element of array
will be skipped– daniel.szaniszlo
Nov 15 '17 at 0:23
I think not because
i--
reduces the index. If you do array.length-1
then the last element of array
will be skipped– daniel.szaniszlo
Nov 15 '17 at 0:23
1
1
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrement
i
. for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)– Izzy
Nov 15 '17 at 11:53
Ah I see, but I must argue a bit that it is not so readable. Even tho I'm not beginner, at first glance I also didn't saw that inside check block of for loop you decrement
i
. for( var i = array.length-1; i>=0; i-- )
is much more cleaner (and it produces same effect)– Izzy
Nov 15 '17 at 11:53
add a comment |
up vote
8
down vote
Another simple solution to digest an array elements once:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
add a comment |
up vote
8
down vote
Another simple solution to digest an array elements once:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
add a comment |
up vote
8
down vote
up vote
8
down vote
Another simple solution to digest an array elements once:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
Another simple solution to digest an array elements once:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
answered Nov 17 '16 at 16:40
Pablo
3,29152843
3,29152843
add a comment |
add a comment |
up vote
3
down vote
If you are e using ES6+ - why not just use Array.filter method?
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
Note that modifying the array element during filter iteration only works for objects and will not work for array of primitive values.
add a comment |
up vote
3
down vote
If you are e using ES6+ - why not just use Array.filter method?
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
Note that modifying the array element during filter iteration only works for objects and will not work for array of primitive values.
add a comment |
up vote
3
down vote
up vote
3
down vote
If you are e using ES6+ - why not just use Array.filter method?
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
Note that modifying the array element during filter iteration only works for objects and will not work for array of primitive values.
If you are e using ES6+ - why not just use Array.filter method?
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
Note that modifying the array element during filter iteration only works for objects and will not work for array of primitive values.
answered Nov 29 '17 at 7:28
Rubinsh
2,72652737
2,72652737
add a comment |
add a comment |
up vote
1
down vote
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
add a comment |
up vote
1
down vote
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
add a comment |
up vote
1
down vote
up vote
1
down vote
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
answered Dec 15 '16 at 15:33
Dmitry Ragozin
554
554
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
add a comment |
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
4
4
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
A good answer will always have an explanation of what was done and why it was done in such a manner, not only for the OP but for future visitors to SO.
– B001ᛦ
Dec 15 '16 at 15:53
add a comment |
up vote
0
down vote
Try to relay an array into newArray when looping:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = ;
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
add a comment |
up vote
0
down vote
Try to relay an array into newArray when looping:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = ;
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
add a comment |
up vote
0
down vote
up vote
0
down vote
Try to relay an array into newArray when looping:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = ;
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
Try to relay an array into newArray when looping:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = ;
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
answered Jan 28 '16 at 15:54
Zon
4,92743551
4,92743551
add a comment |
add a comment |
up vote
0
down vote
You can just look through and use shift()
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
add a comment |
up vote
0
down vote
You can just look through and use shift()
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
add a comment |
up vote
0
down vote
up vote
0
down vote
You can just look through and use shift()
You can just look through and use shift()
edited Aug 29 '17 at 14:41
Ivan
5,16931339
5,16931339
answered Aug 29 '17 at 14:06
user8533067
171
171
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
add a comment |
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
2
2
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
Please add an example using this method.
– Ivan
Aug 29 '17 at 14:41
add a comment |
up vote
0
down vote
There are lot of wonderful answers on this thread already. However I wanted to share my experience when I tried to solve "remove nth element from array" in ES5 context.
JavaScript arrays have different methods to add/remove elements from start or end. These are:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Essentially none of the above methods can be used directly to remove nth element from the array.
A fact worth noting is that this is in contrast with java iterator's
using which it is possible to remove nth element for a collection
while iterating.
This essentially leaves us with only one array method Array.splice
to perform removal of nth element (there are other things you could do with these methods as well, but in the context of this question I am focusing on removal of elements):
Array.splice(index,1) - removes the element at the index
Here is the code copied from original answer (with comments):
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
Another noteworthy method is Array.slice
. However the return type of this method is the removed elements. Also this doesn't modify original array. Modified code snippet as follows:
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
Having said that, we can still use Array.slice
to remove nth element in the following way and as you can observe it is lot more code (hence inefficient)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
The
Array.slice
method is extremely important to achieve
immutability in functional programming à la redux
add a comment |
up vote
0
down vote
There are lot of wonderful answers on this thread already. However I wanted to share my experience when I tried to solve "remove nth element from array" in ES5 context.
JavaScript arrays have different methods to add/remove elements from start or end. These are:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Essentially none of the above methods can be used directly to remove nth element from the array.
A fact worth noting is that this is in contrast with java iterator's
using which it is possible to remove nth element for a collection
while iterating.
This essentially leaves us with only one array method Array.splice
to perform removal of nth element (there are other things you could do with these methods as well, but in the context of this question I am focusing on removal of elements):
Array.splice(index,1) - removes the element at the index
Here is the code copied from original answer (with comments):
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
Another noteworthy method is Array.slice
. However the return type of this method is the removed elements. Also this doesn't modify original array. Modified code snippet as follows:
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
Having said that, we can still use Array.slice
to remove nth element in the following way and as you can observe it is lot more code (hence inefficient)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
The
Array.slice
method is extremely important to achieve
immutability in functional programming à la redux
add a comment |
up vote
0
down vote
up vote
0
down vote
There are lot of wonderful answers on this thread already. However I wanted to share my experience when I tried to solve "remove nth element from array" in ES5 context.
JavaScript arrays have different methods to add/remove elements from start or end. These are:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Essentially none of the above methods can be used directly to remove nth element from the array.
A fact worth noting is that this is in contrast with java iterator's
using which it is possible to remove nth element for a collection
while iterating.
This essentially leaves us with only one array method Array.splice
to perform removal of nth element (there are other things you could do with these methods as well, but in the context of this question I am focusing on removal of elements):
Array.splice(index,1) - removes the element at the index
Here is the code copied from original answer (with comments):
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
Another noteworthy method is Array.slice
. However the return type of this method is the removed elements. Also this doesn't modify original array. Modified code snippet as follows:
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
Having said that, we can still use Array.slice
to remove nth element in the following way and as you can observe it is lot more code (hence inefficient)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
The
Array.slice
method is extremely important to achieve
immutability in functional programming à la redux
There are lot of wonderful answers on this thread already. However I wanted to share my experience when I tried to solve "remove nth element from array" in ES5 context.
JavaScript arrays have different methods to add/remove elements from start or end. These are:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Essentially none of the above methods can be used directly to remove nth element from the array.
A fact worth noting is that this is in contrast with java iterator's
using which it is possible to remove nth element for a collection
while iterating.
This essentially leaves us with only one array method Array.splice
to perform removal of nth element (there are other things you could do with these methods as well, but in the context of this question I am focusing on removal of elements):
Array.splice(index,1) - removes the element at the index
Here is the code copied from original answer (with comments):
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
Another noteworthy method is Array.slice
. However the return type of this method is the removed elements. Also this doesn't modify original array. Modified code snippet as follows:
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
Having said that, we can still use Array.slice
to remove nth element in the following way and as you can observe it is lot more code (hence inefficient)
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
The
Array.slice
method is extremely important to achieve
immutability in functional programming à la redux
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter else it would run into IndexOutBounds exception
{
if (arr[i] === "four" || arr[i] === "two") {
//splice modifies the original array
arr.splice(i, 1); //never runs into IndexOutBounds exception
console.log("Element removed. arr: ");
} else {
console.log("Element not removed. arr: ");
}
console.log(arr);
}
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Element removed. arr: ");
console.log(arr.slice(i, i + 1));
console.log("Original array: ");
console.log(arr);
}
}
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
var arr = ["one", "two", "three", "four"];
var i = arr.length; //initialize counter to array length
while (i--) //decrement counter
{
if (arr[i] === "four" || arr[i] === "two") {
console.log("Array after removal of ith element: ");
arr = arr.slice(0, i).concat(arr.slice(i + 1));
console.log(arr);
}
}
answered Nov 6 at 16:24
Bhanu Devapatla
515512
515512
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9882284%2flooping-through-array-and-removing-items-without-breaking-for-loop%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
7
In addition to iterating backwards and adjust length, you can also just put the members you want into a new array.
– RobG
Mar 27 '12 at 2:09