const test=require("node:test");
const assert=require("assert");
class Filtered {
constructor(list,predicate) {
this.list = list;
this.predicate = predicate
}
[Symbol.iterator]() {
return new FilteredIterator(this);
}
}
class FilteredIterator {
constructor(obj) {
this.obj = obj;
this.index = 0;
}
next () {
while (this.index < this.obj.list.length &&
!this.obj.predicate(this.obj.list[this.index])) {
this.index++;
}
if (this.index >= this.obj.list.length) {
return {done: true}
} else {
let val = this.obj.list[this.index];
this.index++;
return {done: false, value: val}
}
}
}
test("empty", (t)=> {
let results = [];
for (let f of new Filtered([],(x)=>true)) { results.push(f); }
assert.deepStrictEqual(results,[]);
});
test("nonempty", (t)=> {
let results = [];
let filter_obj = new Filtered([1,2,3,4],(x)=>(x % 2 == 0))
for (let f of filter_obj) { results.push(f); }
assert.deepStrictEqual(results,[2,4]);
});
test("big", (t)=> {
let input = [], results=[];
for (let i=0; i<100; i++){ input.push(i);}
let filter_obj = new Filtered(input, (n) => n % 4 == 0 && n*n < 100);
for (let f of filter_obj) { results.push(f); }
assert.deepStrictEqual(results,[0,4,8]);
});
test("restart", (t)=> {
let results1 = [];
let filter_obj = new Filtered([1,2,3,4],(x)=>(x % 2 == 0));
for (let f of filter_obj) { results1.push(f); }
assert.deepStrictEqual(results1,[2,4]);
let results2 = [];
for (let f of filter_obj) { results2.push(f); }
assert.deepStrictEqual(results2,[2,4]);
});