1

I want to remove an item from an array, is array.splice(x,1) the best way to go?

Is array.splice(x,1) functionally equivalent to delete array[x]; array.length-=1 ?

I've read these threads: Javascript object with array, deleting does it actually remove the item? and Deleting array elements in JavaScript - delete vs splice

and did some tests:

<script>
var arr=[];
for(var x=0;x<100000;++x){
    arr.push(x);
}
var a=new Date().getTime();
for(var x=0;x<50000;++x){
    arr.splice(49999,1);
}
var b=new Date().getTime();
alert(b-a);
</script>

<script>
var arr=[];
for(var x=0;x<100000;++x){
    arr.push(x);
}
var a=new Date().getTime();
for(var x=0;x<50000;++x){
    delete arr[49999];
    arr.length-=1;
}
var b=new Date().getTime();
alert(b-a);
</script>

The timing difference is over a magnitude of 100, making the itch to use the second solution almost irresistable.. but before using it, I would like to ask this question: are there any traps i should look out for when i use delete array[x]; array.length-=1 instead of array.splice(x,1)?

Community
  • 1
  • 1
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    The second snippet doesn't do what you want: you're trying to delete element `49999` over and over again, instead of the last element. Moreover, if you want to delete something in the middle of the array, you can't simply `delete` that item and decrease the `length` property by 1. – Marcel Korpel Jun 13 '11 at 13:38
  • @marc you should put that as an answer. it's brilliant – Pacerier Jun 13 '11 at 14:00
  • 1
    No, it's not an answer to your actual question, only a remark. Tomalak's answer is better, so I upvoted him. – Marcel Korpel Jun 13 '11 at 14:05
  • 1
    [Your benchmark is flawed](http://jsperf.com/pop-vs-len) – Raynos Jun 13 '11 at 14:29

4 Answers4

3

If you're just lopping off the last element in the array, you can use pop() and throw away the result or just decrement the length by 1. The delete operator isn't even required here, and splice() is more appropriate for other uses.

Specifically, section 15.4 of the ECMAScript specification says:

whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted.

Both methods mentioned are outlined at MDC:

Either are appropriate for your situation - by all means modify length if you get better performance from it.

Andy E
  • 338,112
  • 86
  • 474
  • 445
2

array.splice may perform other internal operations relevant to the splice.

Your delete array[x]; array.length-=1 just hacks around the public interface and assumes that there's nothing else to do internally.

In fact, this is the cause of the timing difference: there is plenty more to do internally in order to actually splice the array.

Use the proper interface. That's why it's there.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • like what else are there to do if say assuming `delete array[x]; array.length-=1;` works.. (but after Marcel's comment i know it doesn't, i mean assuming if it did worked) – Pacerier Jun 13 '11 at 14:22
  • @Pent: Don't assume it works. Because it doesn't. Use the proper interface. – Lightness Races in Orbit Jun 13 '11 at 14:25
  • @Pent: internally, splice has to move the elements *after* the end position to the starting position of the removed items, as well as adjust the length property and return a newly created array containing those removed items. This is why `splice()` isn't the appropriate method for what you're doing (because it does more than you need it to do whilst other approaches do exactly the right amount). Ignoring the unnecessary `delete` statement, `array.length-=1` will work and is perfectly fine. – Andy E Jun 13 '11 at 14:26
  • @AndyE: Indeed, `pop` would have been better for the specific use case. But I'm answering the question. – Lightness Races in Orbit Jun 13 '11 at 14:27
2

Using delete does not delete the element. After delete somearr[n] somearr[n] still exists but its value is undefined. There are a few ways to remove elements from arrays.

  • within an array for one ore more elements: Array.splice
  • from the end of an array (i.e. the last element): Array.pop() or maybe Array.length = Array.length-1
  • from the beginning of an array (i.e. the first element): Array.shift() or Array.slice(1)

To be complete, using Array.slice you could make up a function too:

function deleteElementsFromArray(arr,pos,n){
  return arr.slice(0,pos).concat(arr.slice(pos+n));
}
KooiInc
  • 119,216
  • 31
  • 141
  • 177
1

Deleting array elements just sets them to undefined - that's why it is so fast. It does not remove the element. Decreasing the length of the array makes it even worse as the array length doesn't change at all!

In other words: the response to your question title is no and you should use splice() to achieve the intended effect. You can use the delete 'trick' to achieve greater performance only if your code handles the possibility of undefined elements. That can be useful, but it has nothing to do with 'removing an item from an array'.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
  • And before ECMA-262, 5th edition, one could even define undefined to some value, which makes undefined really bad. – Yet Another Geek Jun 13 '11 at 13:38
  • 1
    @Yet – that doesn't matter in this case, as using `delete` always sets the element's value to `undefined`, no matter if you set the value of `undefined` to something else. That's only important when you're using the primitive yourself. – Marcel Korpel Jun 13 '11 at 13:40
  • 1
    I'm not sure how appropriate it is to recommend the use of `splice()` to do the job of `pop()`. For the intents and purposes of this question, either `pop()` or `length-=1` makes sense, but `splice()` and `delete` do not. – Andy E Jun 13 '11 at 14:08