# Array.prototype.remove

**URL:** <https://es.discourse.group/t/array-prototype-remove/760>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [May 3, 2021, 10:51pm UTC](https://es.discourse.group/t/array-prototype-remove/760 "2021-05-03T22:51:54Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 3, 2021, 10:51pm UTC](https://es.discourse.group/t/array-prototype-remove/760/1 "2021-05-03T22:51:54Z")

</div>

JavaScript only has one function for removing an arbitrary item from an Array ([splice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)). While splice is more versatile than a simple remove method, it has two drawbacks:

1. It isn't very intuitive for new programmers.
2. Code that moves items from one list to another is unnecessarily verbose.

Compare:

```javascript
const item = list.splice(index, 1)[0];
otherList.push(item);

```

to

```javascript
const item = list.remove(index);
otherList.push(item);

```

Would it be reasonable to add a remove(index) function to Array that works the same as List.remove in Java?

EDIT: As noted below, it would be logical to include Array.prototype.insert in the proposal as well.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [May 3, 2021, 11:08pm UTC](https://es.discourse.group/t/array-prototype-remove/760/2 "2021-05-03T23:08:13Z")

</div>

It doesn't seem like a good idea to add another mutating method to Array.prototype - this code seems like it'd be better with `.filter` rather than mutation.

---

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 3, 2021, 11:28pm UTC](https://es.discourse.group/t/array-prototype-remove/760/3 "2021-05-03T23:28:17Z")

</div>

Hi, ljharb. I know it's hard to tell without more context, but the above example isn't trying to create a specific subset of the original data, so I don't think a filter would be idiomatic (or efficient) here.

The use case is specifically about a user choosing specific items to move to another list (like moving an item to a shopping cart or dropping equipment in a video game), so mutation is necessary and intentional.

---

<div class="post-metadata">

**Author:** ![claudepache](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudepache/32/236_2.png) [@claudepache](https://es.discourse.group/u/claudepache)\
**Post date:** [May 4, 2021, 7:24am UTC](https://es.discourse.group/t/array-prototype-remove/760/4 "2021-05-04T07:24:35Z")

</div>

We have

- `.shift()` and `.unshift(...items)` for removing and adding items at the start of the array;
- `.pop()` and `.push(...items)` for removing and adding items at the end of the array;

it seems reasonable to have

- `.remove(index)` and `.insert(index, ...items)` for removing and adding items in the middle of the array.

Having scan my code, I have found the following uses of `.splice()`:

1. removing one item in the middle of the list;
2. removing all items from a specific position to the end of the list;
3. retrieving and removing a bunch of items at the beginning of the list;
4. adding one element in the middle of the list;
5. adding several elements in the middle of the list;
6. replacing one element at a specific position of the list with a variable number of elements;

One specific issue of `.splice` is that it is commonly used for two opposite operations, namely removing and inserting, and you have to look at the value of a specific argument, which is often 1 or 0, in order to know what it does. Returning to my use cases above let’s compare:

- (1) `list.splice(index, 1)` vs. `list.remove(index)`
- (4) `list.splice(index, 0, [item])` vs. `list.insert(index, item)`
- (5) `list.splice(index, 0, items)` vs. `list.insert(index, ...items)`

and, again, consider the symmetry between `.shift()`, `pop()` and `.remove()` on the one hand, and `.unshift()`, `.push()` and `.insert()` on the other hand.

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [May 4, 2021, 2:07pm UTC](https://es.discourse.group/t/array-prototype-remove/760/5 "2021-05-04T14:07:08Z")

</div>

I actually almost never use .splice() (I might use it for removing items, but I generally don't use it for insertion). I tend to prefer using other array methods to achieve the same result.

These are generally the solutions I reach for to avoid splice():

```javascript
// removing one item in the middle of the list; (though I would probably use .splice() here)
myList = [...myList.slice(0, 2), ...myList.slice(3)]

// removing all items from a specific position to the end of the list;
myList = myList.slice(2)

// retrieving and removing a bunch of items at the beginning of the list;
const front = myList.slice(0, 2)
myList = myList.slice(2)

// adding one element in the middle of the list;
myList = [...myList.slice(0, 2), 'x', ...myList.slice(2)]

// adding several elements in the middle of the list;
myList = [...myList.slice(0, 2), 'x', 'y', 'z' ,...myList.slice(2)]

// replacing one element at a specific position of the list with a variable number of elements;
myList = [...myList.slice(0, 2), 'x', 'y', 'z' ,...myList.slice(3)]

```

The above solutions have the nice benefit that they don't modify the original array, and can be used to make functions more pure. If the performance is needed, then a .remove()/.insert() could be faster, although in-place modifications in the middle of an array is still a slow operation, and code that _really_ needs the performance will sometimes be better off reaching for a linked-list.

I also find myself often creating little helper functions at the top of files where I need additional array operations that JavaScript doesn't provide. e.g.

```javascript
const insertIntoArray = (array, index, items) => items.splice(index, 0, ...items)

```

The addition of .remove()/.insert() would be helpful and nice (Users of other languages would expect to find these methods, .splice() isn't readable, it can be more performant, it'll pair well with the existing .push()/.pop()/.shift()/.unshift() methods, etc). In general, I would welcome this addition to the language, but, at least for me in practice, I don't think I would use it all that much over the pure solutions I'm currently using instead.

---

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 5, 2021, 2:53pm UTC](https://es.discourse.group/t/array-prototype-remove/760/6 "2021-05-05T14:53:26Z")

</div>

claudepache, would you be my champion for this?

---

<div class="post-metadata">

**Author:** ![claudepache](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudepache/32/236_2.png) [@claudepache](https://es.discourse.group/u/claudepache)\
**Post date:** [May 5, 2021, 4:04pm UTC](https://es.discourse.group/t/array-prototype-remove/760/7 "2021-05-05T16:04:14Z")

</div>

I’m not part of TC39; you should find a TC39 member that supports it. But I can participate in writing the proposal.

---

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 7, 2021, 2:57pm UTC](https://es.discourse.group/t/array-prototype-remove/760/8 "2021-05-07T14:57:20Z")

</div>

Could you take another look at this? Other commenters have given some compelling reasons to include it in the language.

---

<div class="post-metadata">

**Author:** ![Clemdz](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/clemdz/32/813_2.png) [@Clemdz](https://es.discourse.group/u/Clemdz)\
**Post date:** [May 7, 2021, 4:39pm UTC](https://es.discourse.group/t/array-prototype-remove/760/9 "2021-05-07T16:39:10Z")

</div>

I had the same thoughts as you about the `splice` method, and actually I'd be curious to know why, back in the days this was implemented, they chose this approach instead of the classic `insert` / `remove` / `replace` methods!

Also, I'd like to propose alternative names for those methods:

- `removeAt` instead of `remove`
- `insertAt` instead of `insert`

The benefits I see is that we directly know we are dealing with indexes, especially for the `remove` method. For the `insert` method, this would enforce the idea that the index comes first, so that we no longer have doubts whether it is `insert(index, element)` or `insert(element, index)`.

Also, this could leave room for a potential `remove(item)` method, that would remove the first occurrence of the given item in the array, like in python. Such a function would also be really great, as for now we have to do it in two steps:

- first, store the element index in the array with `indexOf`
- then, splice at the given index if the index is not -1, because else it would remove the last item (gotcha!)

Such a `remove(item)` method would ease removing items from an array by a lot.

Finally, I'd like to propose that for the ones that need or want to not mutate the original array, we could create these methods alongside the [Change Array by copy](https://github.com/tc39/proposal-change-array-by-copy) proposal, so we would also have the corresponding methods:

- `insertedAt(index, ...items) -> Array`
- `removedAt(index) -> Array`
- `removed(item) -> Array`

What do you think about all of this ?

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [May 7, 2021, 5:10pm UTC](https://es.discourse.group/t/array-prototype-remove/760/10 "2021-05-07T17:10:42Z")

</div>

Yes - insertAt and removeAt are much better names. One of my hesitations with remove() was that it wasn't clear what type of argument it expected - python's remove() was called the same thing but meant something different. It quickly starts to become confusing which methods do what.

I presume the reason .splice() exists the way it does was for performance. If you have to insert something in the middle of an array, you need to shift everything in front of that element forward to make room for it. Similarly, removing an array element shifts everything after it to the left. Javascript has to do half the work if you do both operations at the same time in splice(). In practice, this isn't very common to do.

I would rather have the immutable versions in the language over the mutable ones, (so I would be happy if those were the only ones that made it in), but I'm not against the mutable ones.

---

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 8, 2021, 2:37am UTC](https://es.discourse.group/t/array-prototype-remove/760/11 "2021-05-08T02:37:21Z")

</div>

Clemdz, I agree that `removeAt` and `insertAt` with the possibility of `remove(item)` sound much better than `remove`/`insert`, and having the side-effect free versions sounds reasonable too.

Regarding [Change Array by Copy](https://github.com/tc39/proposal-change-array-by-copy): Are you saying to combine the proposals? I could see "mixed concerns" being a possible objection.

---

<div class="post-metadata">

**Author:** ![Clemdz](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/clemdz/32/813_2.png) [@Clemdz](https://es.discourse.group/u/Clemdz)\
**Post date:** [May 8, 2021, 7:39am UTC](https://es.discourse.group/t/array-prototype-remove/760/12 "2021-05-08T07:39:05Z")

</div>

No no, when I say creating these methods alongside the Change Array by copy proposal, I mean: keep track of the advancement of the Change Array by copy proposal, to see how it evolves along the different TC39 stages, and adapt the immutable versions of this proposal accordingly! :)

---

<div class="post-metadata">

**Author:** ![aebabis](https://avatars.discourse-cdn.com/v4/letter/a/ce73a5/32.png) [@aebabis](https://es.discourse.group/u/aebabis)\
**Post date:** [May 8, 2021, 3:14pm UTC](https://es.discourse.group/t/array-prototype-remove/760/13 "2021-05-08T15:14:19Z")

</div>

Got it. That sounds like a good idea.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [May 9, 2021, 2:55am UTC](https://es.discourse.group/t/array-prototype-remove/760/14 "2021-05-09T02:55:57Z")

</div>

I don't see it as a performance argument so much as a flexibility argument: one method to rule them all.

I'd still like a way to filter in-place or at the very least remove individual values - it'd remove the need for a lot of `for` loops I write.
