tc39/proposal-array-filtering

In place

mixtur opened this issue · 2 comments

Not sure if it is the right place to suggest this, but.

Sometimes you don't want to alloc another array with .filter. It is either when you want to avoid an unnecessary allocation, or when you want to free a garbage collector from doing unnecessary work.

  • when the original array is large and you don't care about the unfiltered version
  • when you have to filter a lot of small arrays and you don't care about the unfiltered version
  • when you do a chain like xs.map(f1).filter(f2)...

It is still a linear time operation:

function filterInPlace(xs, predicate) {
  let writeIndex = 0;
  for (let readIndex = 0; readIndex < xs.length; readIndex++) {
    if (predicate(xs[readIndex], readIndex, xs) {
      xs[writeIndex++] = xs[readIndex];
    }
  }
  xs.length = writeIndex;
}

In spirit of this proposal one would also have to add rejectInPlace with predicate used to reject elements instead of keeping them.

It would be nice if something like that were in the standard. Probably on the array prototype, but anything goes I guess.

I think adding any more in-place methods, ever, is a bad idea. If you use a non-mutating method in a way that would have worked for a mutating one, the engine should be able to optimize that.

Separately, i think iterator helpers would address your performance concern without requiring any mutation.

I agree with @ljharb here. I've often found the mutating array methods to be unintentionally confusing (especially sort). Proper naming could help here, but I don't predict the committee will be receptive to it.