Array.prototype.remove(item)
Bob Myers
rtm at gol.com
Fri Nov 10 11:41:45 UTC 2017
What's wrong with this?
```js
function removeFromArray(array, pred) {
let changed = false;
let j = 0;
for (elt of array) {
if (pred(elt)) changed = true;
else array[j++] = elt;
}
array.length = j;
return changed;
}
```
Bob
On Fri, Nov 10, 2017 at 4:08 PM, Isiah Meadows <isiahmeadows at gmail.com>
wrote:
> I find myself frequently using this code to remove an item from an array:
>
> ```js
> var index = array.indexOf(item)
> if (index >= 0) array.splice(index, 1)
> ```
>
> That's nice, but there's a couple problems:
>
> 1. It only removes the first element, not all occurrences in the array
> (which is usually what you want).
> 2. I know of no engine that fuses those calls, and it'd be rather
> difficult to do so.
>
> My proposal is this: add a new `Array.prototype.remove(item)` method
> that basically does this:
>
> - Accept a list of items to remove, passed as arguments.
> - Remove all instances of those items from the array.
> - Return `true` if any entries were removed, `false` otherwise.
>
> And in the process, it should take care to do it in an optimized
> fashion, avoiding the overhead of allocation, excess reads/writes, and
> excess branching.
>
> In case you're curious why I'm not using `Set`, here's why that's
> ill-equipped in many cases:
>
> - Sets take up a *lot* more memory than arrays, by necessity.
> - Sets are stored typically in tree-like structures, making for poor
> iteration performance.
> - If you're frequently iterating, but infrequently adding/removing,
> these two will quickly kill your performance.
>
> It rarely comes up in day-to-day coding, but the difference is
> substantial when you're writing lower-level data structures and
> performance-sensitive code. It's probably down a similar vein to
> `Array.prototype.copyWithin`, which was pretty much designed for
> `memcpy` or `memmove`.
>
> Here would be a polyfill of what I'd like to propose (it uses a
> minimum of writes, by design, and it does everything in one pass):
>
> ```js
> if (typeof Array.prototype.remove !== "function") {
> // Private utility
> const includes = (items, itemLength, entry) => {
> for (let j = 0; j < itemLength; j++) {
> if (items[j] === entry) return true
> }
>
> return false
> }
>
> Array.prototype.remove = function (item) {
> const oldLength = this.length
> const newLength = arguments.length
> // This is technically observably no different than
> const items = [...arguments]
> let newLength = 0
>
> for (let i = 0; i < oldLength; i++) {
> const entry = this[i]
> if (includes(items, newLength, entry)) {
> let newLength = i++
>
> while (i !== list.length) {
> const entry = this[i]
> if (!includes(items, newLength, entry)) {
> this[newLength++] = entry
> }
> i++
> }
>
> this.length = newLength
> for (let i = newLength; i < oldLength; i++) delete this[i]
> return true
> }
> }
>
> return false
> }
> }
> ```
>
> If the variadic version wasn't accepted, there's also the non-variadic
> version:
>
> ```js
> if (typeof Array.prototype.remove !== "function") {
> Array.prototype.remove = function (item) {
> const oldLength = this.length
> let newLength = 0
>
> for (let i = 0; i < oldLength; i++) {
> const entry = this[i]
> if (entry === item) {
> let newLength = i++
>
> while (i !== list.length) {
> const entry = this[i]
> if (entry !== item) this[newLength++] = entry
> i++
> }
>
> this.length = newLength
> for (let i = newLength; i < oldLength; i++) delete this[i]
> return true
> }
> }
>
> return false
> }
> }
> ```
>
> -----
>
> Isiah Meadows
> me at isiahmeadows.com
>
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> www.isiahmeadows.com
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171110/e61ea2f8/attachment-0001.html>
More information about the es-discuss
mailing list