javascript - Array.prototype.filter() 的就地替代方法是什么

标签 javascript functional-programming

我有一个数组,我想从中删除一些元素。我不能使用 Array.prototype.filter(),因为我想就地修改数组(因为它节省了内存分配,而且对我来说更重要的是,它使我的代码更简单用例)。是否有我可以使用的 filter 的就地替代方案,可能类似于 Array.prototype.forEach() can be used as an in-place variant to Array.prototype.map() 的方式?

编辑:应要求提供的最小示例:

function someCallback(array) {
  // do some stuff
  array.filterInPlace(function(elem) {
    var result = /* some logic */
    return result;
  })
  // do some more stuff
}

最佳答案

Is there an in-place alternative to filter

不,但是自己编写并不难。这是一种挤出所有不符合条件的值的方法。

function filterInPlace(a, condition) {
  let i = 0, j = 0;

  while (i < a.length) {
    const val = a[i];
    if (condition(val, i, a)) a[j++] = val;
    i++;
  }

  a.length = j;
  return a;
}

condition 被设计为与传递给 Array#filter 的回调具有相同的签名,即 (value, index, array)。为了与 Array#filter 完全兼容,您还可以接受第四个 thisArg 参数。

使用forEach

使用 forEach 有一个小优点,那就是它会跳过空槽。这个版本:

  • 用空槽压缩数组
  • 实现 thisArg
  • 如果我们还没有遇到失败的元素,则跳过赋值

function filterInPlace(a, condition, thisArg) {
  let j = 0;

  a.forEach((e, i) => { 
    if (condition.call(thisArg, e, i, a)) {
      if (i!==j) a[j] = e; 
      j++;
    }
  });

  a.length = j;
  return a;
}

a = [ 1,, 3 ];
document.write('<br>[',a,']');

filterInPlace(a, x=>true);
document.write('<br>[',a,'] compaction when nothing changed');

b = [ 1,,3,,5 ];
document.write('<br>[',b,']');

filterInPlace(b, x=>x!==5);
document.write('<br>[',b,'] with 5 removed');

关于javascript - Array.prototype.filter() 的就地替代方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37318808/

相关文章:

javascript - ScrollTop 具有多个 anchor 的偏移粘性栏

javascript - 如何呈现项目列表而不是键

Scala 类型检查编译错误

haskell - 如果 applicative 就足够了,为什么序列需要 monad?

javascript - XMP 对象需要 setProperty 语法

javascript - 通过 $filter 创建和使用新的 `filter`

programming-languages - 闭包中的副作用,它们仍然是纯功能性的吗?

object - 闭包和对象

javascript - 将 div 的内容制作成可移动的可调整大小的按钮

python - 有没有办法检查函数输出是否分配给 Python 中的变量?