Lazy Evaluation Pipeline
JavaScript
class Pipe {
constructor(sequence) {
this.sequence = sequence[Symbol.iterator]()
}
[Symbol.iterator]() {
return this.sequence;
}
where(predicate) {
const sequence = this.sequence
return step(function*() {
for (const item of sequence) {
if (predicate(item)) yield item
}
})
}
take(count) {
const sequence = this.sequence
return step(function*() {
let index = 0;
while (index < count) {
yield sequence.next().value
index++
}
})
}
all() {
return Array.from(this.sequence)
}
}
const pipe = (sequence) => new Pipe(sequence)
const step = (generator) => new Pipe({[Symbol.iterator]: generator})
const books = [
{ title: "Anger Of Silver", rating: 5 },
{ title: "Rat Of Freedom", rating: 3 },
{ title: "Savior Of Dread", rating: 5 },
{ title: "Thieves Of Heaven", rating: 4 },
{ title: "Agents Of Hope", rating: 3 },
{ title: "Edge Of Insanity", rating: 5},
{ title: "Blacksmiths And Friends", rating: 2 },
{ title: "Vultures And Warriors", rating: 4 },
{ title: "Intention Of Freedom", rating: 3 },
{ title: "Searching At The City", rating: 5 },
{ title: "Separated In The Mountains", rating: 2 },
{ title: "Family Of The Banished", rating: 5 },
{ title: "Blinded In My Destiny", rating: 4 },
{ title: "Memory Of The Depths", rating: 3 }
]
const byRating = (b) => {
console.log("where(byRating) called")
return b.rating == 5
}
const result = pipe(books).where(byRating).take(3)
console.log(result.all())