v154 · javascript · iterators
Iterator Includes
"Does this sequence contain that value?" has an answer for arrays and, until now, no answer for iterators — you converted to an array first, which means consuming all of it, including the parts after the match and including the case where there is no end. Iterator.prototype.includes stops at the first match.
concepts
-
Where it stops
An instrumented iterator that counts how many values it is asked for. Compare
includesagainst[...it].includesand watch the difference in how much of the sequence gets consumed — which is the whole feature. -
Sequences with no end
An infinite generator, searched safely. The array version cannot run at all here, so the demo runs it with a guard and reports what it would have done — which is hang.
-
Searching a log
The practical shape: a helper chain over a large record set, asking whether an error code appears. Includes the sharp edge — an iterator is consumed by the search, so the second question gets a different answer.
why it shipped
The iterator helpers gave JavaScript a lazy pipeline: map, filter, take, drop all pull one value at a time. includes completes the set on the consuming end. Without it, the only way to ask a containment question was to materialise the whole sequence, which throws away laziness at the last step and is unavailable entirely for sequences that do not end.
It uses SameValueZero, matching Array.prototype.includes: NaN is found, and +0 and -0 are the same value. That is a deliberate difference from ===, and it is the behaviour people expect from a method with this name.
the API
// Stops at the first match; the rest is never pulled.
const found = logLines().map(parse).includes("E_TIMEOUT");
// Works on sequences that have no end.
naturals().includes(42); // true, after 43 pulls
// SameValueZero, like Array.prototype.includes.
[NaN].values().includes(NaN); // true — === would say false