如何在JavaScript中映射/减少/过滤一个集合?

2022-08-30 01:10:17

有没有办法在JavaScript中/etc a,或者我必须自己写?mapreducefilterSet

以下是一些明智的扩展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中的?mapreduceSet


答案 1

一种简明扼要的方法是通过ES6传播运算符将其转换为数组。

然后,您可以使用所有数组函数。

const mySet = new Set([1,2,3,4]);
[...mySet].reduce(...);

答案 2

从评论中总结一下讨论:虽然没有技术原因可以设置没有,但目前尚未提供,我们只能希望它在ES7中发生变化。reduce

至于 ,单独调用它可能会违反约束,因此它在这里的存在可能是值得商榷的。mapSet

考虑使用函数进行映射 - 它会将集合的大小更改为 1,这可能是也可能不是您想要的。(a) => 42

如果你可以违反它,因为例如,你无论如何都要折叠,你可以在将它们传递给之前在每个元素上应用该部分,从而接受将要减少的中间集合(此时不是Set)可能具有重复的元素。这实质上等效于转换为数组进行处理。mapreduce