Есть ли способ map
/ reduce
/ filter
/ etc a Set
в JavaScript или мне придется написать свой собственный?
Вот несколько разумных 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;
}
Есть ли лучший способ выполнить map
и reduce
использовать Set
в JavaScript?
var s = new Set([1,2,3,4]); s.map((a) => 42);
. Он изменяет количество элементов, чего map
обычно не должно быть. Еще хуже, если вы сравниваете только части сохраненных объектов, потому что тогда технически не указано, какой из них вы получите.
forEach
существует для этого сценария, но почему reduce
тогда нет ?
Set
том, что наборы не являются функторами.