Something similar to question Convert ES6 Iterable to Array. But I only want first N items. Is there any built-in for me to do so? Or how can I achieve this more elegantly?
let N = 100;
function *Z() { for (let i = 0; ; i++) yield i; }
// This wont work
// Array.from(Z()).slice(0, N);
// [...Z()].slice(0, N)
// This works, but a built-in may be preferred
let a = [], t = Z(); for (let i = 0; i < N; i++) a.push(t.next().value);
Array.from() lets you create Array s from: iterable objects (objects such as Map and Set ); or, if the object is not iterable, array-like objects (objects with a length property and indexed elements).
It's explained in detail here: " IterableIterator is an interface defined by TypeScript that combines the contracts of Iterables and Iterator into one. This is because, in some cases, it makes sense to have the Iterable as an Iterator itself, removing the need to have an external class that serves as the iterator."
The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for...of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map , while other types (such as Object ) are not.
To get the first n
values of an iterator
, you could use one of:
Array.from({length: n}, function(){ return this.next().value; }, iterator);
Array.from({length: n}, (i => () => i.next().value)(iterator));
To get the iterator
of an arbitrary iterable
, use:
const iterator = iterable[Symbol.iterator]();
In your case, given a generator function Z
:
Array.from({length: 3}, function(){ return this.next().value; }, Z());
If you need this functionality more often, you could create a generator function:
function* take(iterable, length) {
const iterator = iterable[Symbol.iterator]();
while (length-- > 0) yield iterator.next().value;
}
// Example:
const set = new Set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
console.log(...take(set, 3));
There is no built in method to take only a certain number of items from an iterable (ala something like take()
). Although your snippet can be somewhat improved with a for of
loop, which is specifically meant to work with iterables, eg:
let a = []; let i = 0; for (let x of Z()) { a.push(x); if (++i === N) break; }
Which might be better since your original snippet would continue looping even if there are not N items in the iterable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With