Per*_*ids 16 javascript functional-programming
我有一个数组,我想从中删除一些元素.我无法使用Array.prototype.filter(),因为我想在适当的位置修改数组(因为它节省了内存分配,对我来说更重要的是,在我的用例中使代码更简单).是否存在filter我可以使用的就地替代方案,可能类似于如何Array.prototype.forEach()用作就地变体Array.prototype.map()?
编辑:请求时的最小示例:
function someCallback(array) {
// do some stuff
array.filterInPlace(function(elem) {
var result = /* some logic */
return result;
})
// do some more stuff
}
Run Code Online (Sandbox Code Playgroud)
小智 15
是否存在过滤的就地替代方案
不,但编写自己的并不难.这是一种挤出条件失败的所有值的方法.
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;
}
Run Code Online (Sandbox Code Playgroud)
condition被设计为具有与传递给的回调相同的签名Array#filter,即(value, index, array).为了完全兼容Array#filter,您还可以接受第四个thisArg参数.
forEach使用forEach具有次要优势,它将跳过空插槽.这个版本:
thisArgfunction 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');Run Code Online (Sandbox Code Playgroud)
小智 9
您可以使用以下内容:
array.splice(0, array.length,...array.filter(/*YOUR FUNCTION HERE*/))
Run Code Online (Sandbox Code Playgroud)
说明:
你可以使用什么
Array#filter 返回具有相同元素的数组,但不一定是所有元素。Array#map 为每个循环返回一些东西,结果是一个与源数组长度相同的数组。Array#forEach 什么都不返回,但每个元素都被处理,就像上面一样。Array#reduce 返回你想要的任何东西。Array#some/Array#every返回一个布尔值。但是上面的任何内容都没有在原位改变原始数组的长度问题。
我建议使用 while 循环,从最后一个元素开始并将拼接应用于要删除的元素。
这使索引保持有效并允许为每个循环递减。
例子:
var array = [0, 1, 2, 3, 4, 5],
i = array.length;
while (i--) {
if (array[i] % 2) {
array.splice(i, 1);
}
}
console.log(array);Run Code Online (Sandbox Code Playgroud)
如果您能够添加第三方库,请查看lodash.remove:
predicate = function(element) {
return element == "to remove"
}
lodash.remove(array, predicate)
Run Code Online (Sandbox Code Playgroud)