Если вы не возражаете против перерасширения, первый итератор возвращает только объект.Вы можете проверить, выполнив console.log(typeof arr.select(v => v * 2));
.
Следовательно, вы можете просто определить: Object.prototype.where = function* (fn) {};
Array.prototype.select = function* (fn) {
let it = this[Symbol.iterator]();
for (let item of it) {
yield fn(item);
}
};
Object.prototype.where = function* (fn) {
let it = this[Symbol.iterator]();
for (let item of it) {
if (fn(item)) yield item;
}
};
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = arr.select(v => v * 2)
.where(v => v % 3 === 0);
for (let item of result) {
console.log(item);
}
Если вы хотите, чтобы порядок не имел значения, вы можете расширить как Array, так и Object следующим образом.
Array.prototype.select = function* (fn) {
let it = this[Symbol.iterator]();
for (let item of it) {
yield fn(item);
}
};
Array.prototype.where = function* (fn) {
let it = this[Symbol.iterator]();
for (let item of it) {
if (fn(item)) yield item;
}
};
Object.prototype.select = Array.prototype.select;
Object.prototype.where = Array.prototype.where;
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// Chain 1.
let result1 = arr.select(v => v * 2).where(v => v % 3 === 0);
console.log('Chain 1');
for (const item of result1) {
console.log(item);
}
// Chain 2.
let result2 = arr.where(v => v % 3 === 0).select(v => v * 2);
console.log('Chain 2')
for (const item of result2) {
console.log(item);
}