Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js Iterator interface

I am reading the MDN guide on Iterators and generators and I implemented the following example :

function Range(low, high){
  this.low = low;
  this.high = high;
}
Range.prototype.__iterator__ = function(){
  return new RangeIterator(this);
};

function RangeIterator(range){
  this.range = range;
  this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
  if (this.current > this.range.high)
    throw StopIteration;
  else
    return this.current++;
};

var range = new Range(3, 5);
for (var i in range) {
  console.log(i);
}

But I get this :

low
high
__iterator__

Where it should have returned :

3
4
5

Is it possible to implement this as expected in Node.js?

Note: I am using node --harmony myscript.js.

** Edit **

I should also note that I am aware that __iterator__ is a Mozilla-feature only. I'd like to know what's the equivalent in Node.js. Or what's the next best thing.

Also, I'd like to not use a generator for this as I want the iteration to be free of any conditional tests.

My conclusion is that the only equivalent is

Range.prototype.each = function (cb) {
  for (var i = this.low; i <= this.high; i++) {
     cb(i);
  }
};

//...
range.each(function (i) {
  console.log(i);
});

Are there alternatives?

like image 634
Yanick Rochon Avatar asked Feb 27 '14 15:02

Yanick Rochon


People also ask

What is the difference between iterator and generator?

Iterators are the objects that use the next() method to get the next value of the sequence. A generator is a function that produces or yields a sequence of values using a yield statement. Classes are used to Implement the iterators. Functions are used to implement the generator.

What is IterableIterator?

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."

What is Iterables in JS?

A JavaScript iterable is an object that has a Symbol. iterator. The Symbol. iterator is a function that returns a next() function. An iterable can be iterated over with the code: for (const x of iterable) { }

What is a JS iterator?

In JavaScript an iterator is an object which defines a sequence and potentially a return value upon its termination. Specifically, an iterator is any object which implements the Iterator protocol by having a next() method that returns an object with two properties: value. The next value in the iteration sequence.


2 Answers

I think your code had a bug where you wrote for (var i in range) instead of for (var i of range). The in keyword prints out the object's properties, you want to use of to actually get the iterator values.

Anyway, Node.js now has better harmony support since the question was asked. Here's an updated code sample which works out of the box on Node 4.2. The __iterator__ name was changed to Symbol.iterator, and the StopIteration exception isn't used.

"use strict";

function Range(low, high){
  this.low = low;
  this.high = high;
}
Range.prototype[Symbol.iterator] = function(){
  return new RangeIterator(this);
};

function RangeIterator(range){
  this.range = range;
  this.current = this.range.low;
}
RangeIterator.prototype.next = function(){
  let result = {done: this.current > this.range.high, value: this.current};
  this.current++;
  return result;
};

var range = new Range(3, 5);
for (var i of range) {
  console.log(i);
}
like image 131
andy Avatar answered Oct 22 '22 04:10

andy


Yes it is.

Generators and iterators are part of ECMAScript 6 / JavaScript 1.7. Node has support for them but you need to activate them, when starting you script.

For example:

node --harmony_generators --harmony_iteration your_script.js

Take a look at this blog post for more information.

like image 38
TheHippo Avatar answered Oct 22 '22 04:10

TheHippo