【发布时间】:2018-02-09 13:42:20
【问题描述】:
给定一个 ES6 Map 和谓词函数,我如何安全地删除地图的所有不匹配元素?
我找不到官方的 API 函数,但我可以想到两个实现。第一个不会尝试就地删除,而是创建一个副本:
// version 1:
function filter(map, pred) {
const result = new Map();
for (let [k, v] of map) {
if (pred(k,v)) {
result.set(k, v);
}
}
return result;
}
const map = new Map().set(1,"one").set(2,"two").set(3,"three");
const even = filter(map, (k,v) => k % 2 === 0);
console.log([...even]); // Output: "[ [ 2, 'two' ] ]"
另一个就地删除。在我的测试中,它可以工作,但我没有发现修改地图不会破坏迭代器(for-of 循环)的保证:
// version 2:
function deleteIfNot(map, pred) {
for (let [k, v] of map) {
if (!pred(k,v)) {
map.delete(k);
}
}
return map;
}
const map = new Map().set(1,"one").set(2,"two").set(3,"three");
deleteIfNot(map, (k,v) => k % 2 === 0);
console.log([...map]); // Output: "[ [ 2, 'two' ] ]"
问题:
- 第二个版本(就地删除)在所有平台上都正确吗?
- 有没有更好的方法来实现就地过滤器?也许我错过了一些官方 API?
【问题讨论】:
-
使用函数
filter处理数组意味着您将要修改克隆并返回它。就地修改不是功能(没有副作用)。如果真的要原地修改,只需重新赋值给filter函数的结果即可。