1

At a discussion about Javascript generators someone cooked up an interesting function:

function *foo() {
    var y = 1;
    while(true) yield (y = (y * (yield)));
}

Now, this function can be used via:

var results = [];
var bar = foo();
bar.next();
results.push(bar.next(2));
bar.next();
results.push(bar.next(2));
bar.next();
results.push(bar.next(2));
bar.next();
results.push(bar.next(2));

As we can see, in order to get the next product we need to call next twice. The question is: can this somehow be resolved with a single yield?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175

1 Answers1

2
  while(true) y *=  yield y;

Just yield y and then multiply y with its result.

function *foo() {
    let y = 1;
    while(true) y *=  yield y;
}

const bar = foo();
bar.next();
console.log(bar.next(2).value);
console.log(bar.next(2).value);
console.log(bar.next(2).value);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • 3
    *Just* simplified mine to the same thing. Great minds, though your mind was apparently faster. :-) – T.J. Crowder Nov 08 '18 at 14:59
  • 1
    @NinaScholz - What do you mean by "take 1 as first value"? Once you've primed the generator (which you need to do in order to pass it things -- but perhaps that's the call you mean), this returns 2, then 4, then 8, just like the calls to the generator in the question that the OP is pushing to `results`. One could modify it to accept the initial `y` in the `foo` call. – T.J. Crowder Nov 08 '18 at 15:10
  • 1
    i mean the empty call for moving the first value into the iterator and getting at the same time this first value back ... do i miss something? – Nina Scholz Nov 08 '18 at 15:25