Есть ли способ 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том, что наборы не являются функторами.