JavaScript中有map
/ reduce
/ filter
/ etc和Set
的任何方式,还是我必须自己编写?
这里有一些明智的Set.prototype
扩展
Set.prototype.map = function map(f) {
var newSet = new Set();
for (var v of this.values()) newSet.add(f(v));
return newSet;
};
Set.prototype.reduce = function(f,initial) {
var result = initial;
for (var v of this) result = f(result, v);
return result;
};
Set.prototype.filter = function filter(f) {
var newSet = new Set();
for (var v of this) if(f(v)) newSet.add(v);
return newSet;
};
Set.prototype.every = function every(f) {
for (var v of this) if (!f(v)) return false;
return true;
};
Set.prototype.some = function some(f) {
for (var v of this) if (f(v)) return true;
return false;
};
让我们采取一些措施
let s = new Set([1,2,3,4]);
还有一些愚蠢的小功能
const times10 = x => x * 10;
const add = (x,y) => x + y;
const even = x => x % 2 === 0;
看看它们是如何运作的
s.map(times10); //=> Set {10,20,30,40}
s.reduce(add, 0); //=> 10
s.filter(even); //=> Set {2,4}
s.every(even); //=> false
s.some(even); //=> true
不是很好吗?是的,我也这么认为。将其与丑陋的迭代器用法进行比较
// puke
let newSet = new Set();
for (let v in s) {
newSet.add(times10(v));
}
和
// barf
let sum = 0;
for (let v in s) {
sum = sum + v;
}
有没有更好的方法在JavaScript中使用map
完成reduce
和Set
?
答案 0 :(得分:64)
一种简单的方法是通过ES6扩展运算符将其转换为数组。
然后您可以使用所有数组函数。
const mySet = new Set([1,2,3,4]);
[...mySet].reduce()
答案 1 :(得分:19)
总结评论中的讨论:虽然没有技术原因设置为不有reduce
,但它目前尚未提供,我们只能希望它发生变化在ES7中。
对于map
,单独调用它可能会违反Set
约束,因此它的存在可能存在争议。
考虑使用函数(a) => 42
进行映射 - 它会将集合的大小更改为1,这可能或者可能不是。
如果你违反了这个,那就是无论如何你都要弃去,你可以在将map
部分传递给reduce
之前将其应用于每个元素,从而接受中间集合(不是' ta在此时设置)将要减少的可能有重复的元素。这基本上等同于转换为Array来进行处理。
答案 2 :(得分:6)
map
/ reduce
集合中缺少filter
/ Map
/ Set
的原因似乎主要是概念上的问题。如果Javascript中的每个集合类型实际上都指定了自己的迭代方法,只允许这个
const mySet = new Set([1,2,3]);
const myMap = new Map([[1,1],[2,2],[3,3]]);
mySet.map(x => x + 1);
myMap.map(([k, x]) => [k, x + 1]);
而不是
new Set(Array.from(mySet.values(), x => x + 1));
new Map(Array.from(myMap.entries(), ([k, x]) => [k, x + 1]));
另一种方法是将map / reduce / filter指定为iterable / iterator协议的一部分,因为entries
/ values
/ keys
返回Iterator
s。可以想象,并非每个可迭代的也是可映射的#34;。另一种选择是指定一个单独的收集协议"为了这个目的。
但是,我不知道ES目前关于这个主题的讨论。