Tim Hallyburton
Tim Hallyburton

Reputation: 2929

Create Array from Generator in JavaScript

I want to create an array from the values of an generator in JavaScript. The generator creates a sequence of dynamic length like this

function* sequenceGenerator(minVal, maxVal) {
    let currVal = minVal;

    while(currVal < maxVal)
        yield currVal++;
}

I want to store those values in an array but using next() until the generator is done does not seem to be the best way possible (and looks quite ugly to be honest).

var it, curr, arr;

it = sequenceGenerator(100, 1000);
curr = it.next();
arr = [];

while(! curr.done){
    arr.push(curr.value);
}

Can I somehow create an array directly from/within the generator? If not, can I somehow avoid/hide the loop? Maybe by using map or something like that?

Thanks in advance.

Upvotes: 38

Views: 28099

Answers (4)

dr0p17
dr0p17

Reputation: 1

{let
  isGen = (genProto => (val => genProto.isPrototypeOf(val)))(
    Object.getPrototypeOf(function*(){}) ),
  iterMthdGen = (() => (function() { return this(); })),
  createAddIterMthdFn = (iterMthdFn => ((obj) =>
    Object.assign(obj, {[Symbol.iterator]: iterMthdFn(), }) )),
  addIterMthdGen = createAddIterMthdFn(iterMthdGen),
  wrapGen = (gen => ({[Symbol.iterator]: gen}))
  g = function*() { for(i = 0; i < 10; i++) yield i; };
// [0, 1, 2, 3, 4, 5, 6, 7, 8 , 9],  [0, 1, 2, 3, 4, 5, 6, 7, 8 , 9]
console.log([...wrapGen(g)], [...addIterMthdGen(g)]); }

Using this recipes to work with generators. wrapGen is simpliest method. addIterMthdGen makes generator also an iterable.

Upvotes: -1

Tim Hallyburton
Tim Hallyburton

Reputation: 2929

I found another way

var arr = Array.from( sequenceGenerator(min, max) );

works aswell.

Upvotes: 38

philipp
philipp

Reputation: 16495

One short solution might be:

let list = [...sequenceGenerator(min, max)]

Documentation on MDN

Upvotes: 64

Redu
Redu

Reputation: 26161

You can do it like this;

function* sequenceGenerator() {
  let currVal = this.minVal;
  while(currVal <= this.maxVal) yield currVal++;
}
var obj = {minVal: 10, maxVal:20},
    arr;
obj[Symbol.iterator] = sequenceGenerator;
arr = [...obj];
console.log(arr);

Upvotes: 4

Related Questions