40

Hi I delete an object in an array using two approaches:- splice and filter.

splice code here:-

(this.myArray).splice((this.myArray).indexOf(myobject), 1);

filter code here:-

(this.myArray).filter(obj => obj !== myobject);

Please tell us differences between both and which one is the best approach?

fujy
  • 5,168
  • 5
  • 31
  • 50
Harleen Kaur Arora
  • 1,949
  • 2
  • 23
  • 55

5 Answers5

30

I think chrystian's answer is the right one but I want to add a warning (not related to performance but to avoid a potential undesired bug)

WARNING: One small detail, be careful when you use splice with indexOf. If indexOf returns (-1), that's to say the element wasn't found, splice will remove the last element of the array (negative indexing works).

If you decide to use splice instead of filter take that into consideration and check for the indexOf result before doing splice

RCarranza
  • 702
  • 8
  • 10
24

I think that the main difference here is:

  • splice - lets you remove an element from this particular array
  • filter - won't touch the input array and will create and return new filttered array

angular has nothing to do here and when it comes to speed, splice will win

Tino Hager
  • 898
  • 7
  • 23
chrystian
  • 831
  • 7
  • 15
  • Filter wins in your test. – Amsakanna Apr 10 '18 at 08:06
  • 2
    i see that now results depend on browser, in chromium its indeed filter that wins but on firefox its still splice – chrystian Apr 10 '18 at 12:39
  • In case someone's wondering: both **reindex** the resulting array. `splice` also returns the removed elements - it's similar to `.pop()` but with multiple values. I myself consider `filter` much more *readable* (and just a bit longer). – jave.web May 20 '22 at 05:47
16

In case you know the index using splice would be an O(1) operation while using filter is an O(n) operation.

srfrnk
  • 2,459
  • 1
  • 17
  • 32
  • 6
    I think the WORST case time complexity for splice would actually be O(n) , in situations where the element that you're splicing is located in a position where the entire array needs to be duplicated. However, when using filter, it will ALWAYS be O(n) , so I agree with your assertion that splice is almost always more efficient. In a nutshell, unless the element you're splicing is at the beginning of the array, slice will always be more efficient in terms of time complexity. – Nmuta Mar 15 '19 at 17:09
  • 4
    Also in most of case, we might need indexOf to works with splice, and indexOf which cost O(n); so it is actually O(n) in general. – Weijing Jay Lin May 27 '21 at 17:50
  • 1
    I did my own test and it's clear that `Array.indexOf()` + `Array.splice()` is faster than `Array.filter()`. See https://jsbench.github.io/#cc31a1b26f20546c074f5a0990523606. – Halfist Aug 30 '22 at 10:48
8

Array.splice - will change the Array itself. (use: myArray.splice)
Array.filter - will return the filtered Array. (use: myFilteredArray = Array.filter)
This is a test result on an Array of 30 small objects. I ran it on jsbence.me:
enter image description here

Nadav
  • 1,730
  • 16
  • 20
5

There are several answers regarding performance, but there is another difference that wasn't explicitly mentioned between the two methods you are asking about:

The first method you wrote, using indexOf, will only splice the first reference to myobject in this.myArray, as it says in the documentation,

The indexOf() method returns the first index at which a given element can be found

The second method you asked about using filter, will remove every reference to myobject in this.myArray, in the case that you have multiple references to it in the array. Here is the line from filter's documentation that explains it:

Filter() calls a provided callback function once for each element in an array


And as chrystian said, filter also returns a new array, whereas splice modifies the array it was called on. For clarity, I've written a little gist that shows overloads of both options side-by-side. It has pretty clear documentation about the differences, so feel free to use it if it helps you at all. (If you prefer it as a prototype method, as some people do, here's that as well.) Since this question is specifically about Angular, the gists are in Typescript.
The second part of your question asked which was best. The best approach may be situationally based on two things:

  1. How many times is myobject referenced in this.myArray?
    • If it occurs many times, and you want to remove all references, use filter
    • If it occurs many times, and you only want to remove the first reference, use indexOf
    • If it occurs only once, ask yourself question 2:
  2. Is performance a big concern?
    • If it is, then do a benchmark for it using the engine that will be running the script, and use the most performant method
    • If it isn't, use the one you find easiest to read.
ojsung93
  • 51
  • 1
  • 1