2

Say we have this generator function (generator fn returns an iterator):

function* foo(){
  yield 1;
  yield 2;
  yield 3;
}

for (let i of foo()) {
  console.log(i);
}

we can iterate over the iterator using a for..of loop.

My question is: is there a way to create a functional for-loop to iterate over an iterator like with an Array?

[1,2,3].forEach(function(i){
   // we have our own block scope for each item in the iterable
});

is our best bet this technique?

 for (let i of foo()) {
      (function(i){

      })(i);
 }

seem like there must be an easier way

  • 1
    `Array.from(...iterable...).forEach()`, maybe? – John Ellmore Nov 14 '17 at 06:41
  • 2
    You know that `let` has a [block scope](https://developer.mozilla.org/de-DE/docs/Web/JavaScript/Reference/Statements/let) – Andreas Nov 14 '17 at 06:43
  • WTH is a "*functional for-loop*"? What is your problem that `for (let i of foo())` does not solve? – Bergi Nov 14 '17 at 22:37
  • Functional for-loop is a catch-all phrase for looping constructs like map / filter / forEach. –  Nov 14 '17 at 22:56
  • But yeah I am not that familiar with `for..of`, but maybe it will work just fine with block-scoped let variables - until you transpile to es5 :) –  Nov 14 '17 at 22:58
  • @Bergi will block-scope work (using let) with older versions of JS, like ES5? I don't think so. Thus the need for forEach, right? –  Nov 14 '17 at 22:58
  • @Olegzandr There is no `let` in ES5. Of course there are no generators and iterators in ES5 either, so it does not matter. If you use a transpiler, it will take care of everything (especially the block-scoping). – Bergi Nov 14 '17 at 22:59
  • @Olegzandr Ah. Except that `forEach` is not at all functional - its entire purpose is running side effects :-) – Bergi Nov 14 '17 at 23:00
  • @Bergi maybe you can answer this - https://www.quora.com/unanswered/Does-block-scope-using-let-exist-for-older-versions-of-JavaScript-For-example-transpiling-to-ES5-with-Babel-or-TypeScript-will-eliminate-let-and-change-to-var?srid=Xt2o –  Nov 14 '17 at 23:00
  • @Bergi yeah I agree re: forEach, so if you have a better word than `functional`, I will take it...although map / filter are considered functional programming staples, and forEach does not *necessarily* have side-effects :) –  Nov 14 '17 at 23:01
  • @Olegzandr I think I just answered it (but no I won't post to Quora). A better word might be "(array) iteration methods". – Bergi Nov 14 '17 at 23:02
  • Right, so we need our block-scoped array iteration methods, since `let` won't work when transpiling to ES5.....right? –  Nov 14 '17 at 23:03
  • Amirite or amirite? or amirite –  Nov 14 '17 at 23:04
  • It could be that transpilers transpiling to ES5 from `let` will create block-scope for you using IIFE, but I prefer not having transpiled code changing form *that* much if possible. –  Nov 14 '17 at 23:05
  • I added an answer showing how TypeScript handles block-scope with let using var after transpilation, looks like it redeclares a new var for each iteration of the loop, to solve the problem. –  Nov 18 '17 at 23:42

3 Answers3

0

You can use the second argument of Array.from, which is a map-like callback function:

Array.from(foo(), value => console.log(value));

function* foo(){
  yield 1;
  yield 2;
  yield 3;
}
Array.from(foo(), value => console.log(value));
trincot
  • 317,000
  • 35
  • 244
  • 286
0

Here is how TypeScript transpiles this:

before

const iterator = [1,2,3];

for (let o of iterator) {
  console.log(o);
}

after

var iterator = [1, 2, 3];
for (var _i = 0, iterator_1 = iterator; _i < iterator_1.length; _i++) {
    var o = iterator_1[_i];
    console.log(o);
}

Now here is how TypeScript transpiles this:

before

const iterator = [1,2,3];

Array.from(iterator).forEach(function(o){
  console.log(o);
});

after

var iterator = [1, 2, 3];
Array.from(iterator).forEach(function (o) {
    console.log(o);
});

just something to think about

-1

[...foo()].forEach should be the closest.

A bigger question is why javascript doesn't provide array-like functions for generator/Iterables.

qxg
  • 6,955
  • 1
  • 28
  • 36
  • yeah, seems pretty lame to me, there must be another way –  Nov 14 '17 at 17:52
  • Have a look at [Why do generators not support map()?](https://stackoverflow.com/q/31232415/1048572) – Bergi Nov 14 '17 at 22:48