我有一个数组,我想从中删除一些元素。我不能使用 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/