【发布时间】:2016-01-18 23:53:24
【问题描述】:
有没有办法在 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 中使用 Set 来完成 map 和 reduce?
【问题讨论】:
-
map-reduce-ing
Set的问题在于 Set 不是 Functor。 -
好吧,考虑
var s = new Set([1,2,3,4]); s.map((a) => 42);。它改变了元素的数量,map通常不应该这样做。如果您只比较保留对象的一部分,那就更糟了,因为从技术上讲,您会得到哪个是未指定的。 -
我曾考虑过,但我不确定我(个人)是否会认为这是无效的。好的,所以至少
forEach存在这种情况,但为什么没有reduce呢? -
我会说这是一个疏忽。折叠(减少)一个 Set 非常好。
标签: javascript set ecmascript-6 reduce