如何过滤JavaScript映射?

如何过滤JavaScript映射?,javascript,ecmascript-6,Javascript,Ecmascript 6,给定ES6和谓词函数,如何安全地删除映射的所有不匹配元素 我找不到正式的API函数,但我可以想到两种实现。第一个不会尝试就地删除,而是创建一个副本: //第1版: 函数过滤器(映射、pred){ const result=新映射(); for(让[k,v]为映射){ if(pred(k,v)){ 结果集(k,v); } } 返回结果; } const map=new map().set(1,“一”).set(2,“二”).set(3,“三”); 常量偶数=过滤器(映射,(k,v)=>k%2=

给定ES6和谓词函数,如何安全地删除映射的所有不匹配元素


我找不到正式的API函数,但我可以想到两种实现。第一个不会尝试就地删除,而是创建一个副本:

//第1版:
函数过滤器(映射、pred){
const result=新映射();
for(让[k,v]为映射){
if(pred(k,v)){
结果集(k,v);
}
}
返回结果;
}
const map=new map().set(1,“一”).set(2,“二”).set(3,“三”);
常量偶数=过滤器(映射,(k,v)=>k%2==0);

console.log([…偶数]);//输出:“[[2',两个']]”
ES6可重用项在循环中删除时没有问题

没有一种特殊的API可以在不迭代的情况下有效地过滤ES6映射条目

如果映射不必是不可变的,并且应该就地修改,那么在过滤上创建新映射会带来开销

还有Map
forEach
,但它假定也将使用该值

由于映射仅通过其键进行过滤,因此entry对象没有任何用处。可以通过迭代映射键来改进:

for (let k of map.keys()) {
  if (!(k % 2))
    map.delete(k);
}

如果我们想使用.filter()迭代器,我们可以应用一个简单的技巧,因为ES6映射没有.filter操作符。方法是:

  • 将映射转换为[key,value]对数组
  • 映射或过滤数组
  • 将结果转换回地图
例如:

const map0=新映射([
[a',1],
[b',2],
[c',3]
]);
常量映射1=新映射(
[…map0]
.filter(([k,v])=>v<3)
);
console.info([…map1]);

//[0:[“a”,1],1:[“b”,2]]
使用具有功能的
过滤器的阵列意味着您将要修改克隆并返回该克隆。就地修改不起作用(无副作用)。如果您真的想就地修改,只需将其重新分配给filterfunction的结果。但你的回答涵盖了我想知道的一切。我不确定迭代是否同时修改映射。在其他一些语言(例如,C++、java)中,这将打破,或者只在直接操作迭代器时起作用。我很好奇,与接受的答案相比,这是什么样的性能。是否需要分配中间数组?我不确定。这是一个测试研究的问题。@Lukeyb
[…map0]
.filter(…)
是这里的两个中间数组。当然,数组会导致一定的开销,对于额外的映射来说甚至更大,这比修改现有映射慢很多倍。但仍然可以足够快,只要每秒不处理数千个元素,性能就不是问题。无论如何,如果案例不要求旧的映射是不可变的,那么创建新映射就是浪费资源。@Estus_Flask,在我看来,这里没有“中间”数组。这里给出了map0以显示输入数据结构。因此,任务是如果您有map0(这种结构),如何过滤它并将结果作为另一个map?当然,如果我们有一个数组作为输入,我们就不需要任何映射。另一种编写
[…map0]
的方法是
array.from(map0)