Array.prototype.filter()的原地替代是什么? [英] What is the in-place alternative to Array.prototype.filter()

查看:152
本文介绍了Array.prototype.filter()的原地替代是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组,我想从中删除一些元素。我不能使用 Array.prototype.filter(),因为我想修改数组(因为它节省了内存分配,对我来说更重要的是,代码在我的用例中更简单)。是否有可以替代 filter 的替代方法,可以类似于 Array.prototype.forEach()可以用作 Array.prototype.map()


$ b

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

  function someCallback(array){
//做一些事情
array.filterInPlace(function(elem){
var result = / *一些逻辑* /
返回结果;
})
//做更多的事情
}


解决方案


是否存在过滤器的替代方案

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

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

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

a.length = j;
返回a;
}

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



使用 forEach



使用 forEach 有一个小优点,它会跳过空插槽。此版本:


  • 实现 thisArg

  • 如果我们尚未遇到失败的元素,则指定Skipps



< pre-class =snippet-code-js lang-js prettyprint-override> 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('< ); b = [1,3,...,5]; document.write('< br,'[',b,']'); filterInPlace(b ,x => x!== 5); document.write('<','b,'] with 5 removed');

div>


I've got an array that I would like to remove some elements from. I can't use Array.prototype.filter(), because I want to modify the array in place (because it saves a memory allocation and, more important for me, makes the code more simple in my use case). Is there an in-place alternative to filter that I can use, maybe analogously to how Array.prototype.forEach() can be used as an in-place variant to Array.prototype.map()?

Edit: Minimum example upon request:

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

No, but it's not hard to write your own. Here is an approach which squeezes out all the values which fail a condition.

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 is designed to have the same signature as the callback passed to Array#filter, namely (value, index, array). For complete compatibility with Array#filter, you could also accept a fourth thisArg parameter.

Using forEach

Using forEach has the minor advantage that it will skip empty slots. This version:

  • Compacts arrays with empty slots
  • Implements thisArg
  • Skipps the assignment, if we have not yet encountered a failing element

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');

这篇关于Array.prototype.filter()的原地替代是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆