How to map/reduce/filter a Set in JavaScript?

Is there any way to map/reduce/filter/etc a Set in JavaScript or will I have to write my own?

Here’s some sensible Set.prototype extensions

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 take a little set

let s = new Set([1,2,3,4]);

And some stupid little functions

const times10 = x => x * 10;
const add = (x,y) => x + y;
const even = x => x % 2 === 0;

And see how they work

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

Isn’t that nice ? Yeah, I think so too. Compare that to the ugly iterator usage

// puke
let newSet = new Set();
for (let v in s) {
  newSet.add(times10(v));
}

And

// barf
let sum = 0;
for (let v in s) {
  sum = sum + v;
}

Is there any better way to accomplish map and reduce using a Set in JavaScript?

4 Answers
4

Leave a Comment