I am a beginner reading the chapter Iterators from the book
JavaScript: The Definitive Guide
I am not able to understand the next()
method in the below example from book which is about Creating iterable-based alternative to the filter() method of JavaScript arrays.
// Return an iterable object that filters the specified iterable,
// iterating only those elements for which the predicate returns true
function filter(iterable, predicate) {
let iterator = iterable[Symbol.iterator]();
return { // This object is both iterator and iterable
[Symbol.iterator]() {
return this;
},
next() {
for(;;) {
let v = iterator.next();
if(v.done || predicate(v.value)) {
return v;
}
}
}
};
}
Let's test this function with an array.
let a = [1,2,3,4,5]
let iter = filter(a, x => x>3) // Call the function
// Lets check the returned object of iter.next() method
iter.next() // {value: 4, done: false}
iter.next() // {value: 5, done: false}
iter.next() // {value: undefined, done: true}
I am completely confused about the next()
method here. Please help me in understanding it.
Also, I am not able to understand that... the next()
method contains an infinite for loop. But what it makes it break that loop. There is no condition like that here.
Thanks in Advance
CodePudding user response:
Also, I am not able to understand that... the next() method contains an infinite for loop. But what it makes it break that loop. There is no condition like that here.
return
breaks the loop.
I am completely confused about the next() method here. Please help me in understanding it.
Here's what it's doing:
- It calls
next
to get the next result object, which it stores inv
. - If
v.done
is truthy, it returnsv
(breaking the loop). This means the iterator has reached the end of its sequence. - If
v.done
is falsy, it callspredicate
passing inv.value
; ifpredicate
returns a truthy value,next
returnsv
(breaking the loop).
So the result is that the iterator returned by that filter
function will iterate the values that the predicate returns a truthy value for, and will return a result object with done
set to a truthy value when it reaches the end of the input interable.
I haven't read the recent editions of the book (I bought mine something like 15 years ago), but my guess is that the given code is meant to show how you would use an iterator explicitly, and later Flanagan will introduce for-of
and generator functions, which provide a simpler means of doing that filter
:
function* filter(iterable, predicate) {
for (const element of iterable) {
if (predicate(element)) {
yield element;
}
}
}
Live Example:
I went back and forth between implicit (for-of
, generators) and explicit in Chapter 6 of my recent book JavaScript: The New Toys. I found interleaving them was the best I could do to help get the concepts but also the details across.