Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Iterable<E> in dart?

Tags:

dart

I still havn't understood how to deal with Iterable/Iterator in Dart.

I think I have to give up and simply return Lists but that's not what I want since it will lead bad performance in my case.

What I want is to understand how to implement my own Iterable/Iterator.

Why do both of these attempts fail?

library foo;

import 'dart:collection';

// Both attemps below raises the following error:
// ==============================================
//
// Closure call with mismatched arguments: function 'moveNext'
//
// NoSuchMethodError: incorrect number of arguments passed to method named 'moveNext'
// Receiver: Closure: (dynamic) => Iterator<int> from Function 'iterator':.
// Tried calling: moveNext()


main() {
  Iterable<int> iterable1 = new OddsIterableDartStyle([1,2,4,6,7,8,9]);
  for (int i in iterable1)
    print("ODD: $i");

  Iterable<int> iterable2 = new OddsIterableJavaStyle([1,2,4,6,7,8,9]);
  for (int i in iterable2)
    print("ODD: $i");
}

// ------------------------------------------

class OddsIterableDartStyle extends Object with IterableMixin<int> {
  List<int> _ints;

  OddsIterableDartStyle(this._ints);

  Iterator<int> iterator() {
    return new OddsIterator(this);
  }
}

// ------------------------------------------

class OddsIterableJavaStyle implements Iterable<int> {
  List<int> _ints;

  OddsIterableJavaStyle(this._ints);

  Iterator<int> iterator() {
    return new OddsIterator(this);
  }

}

// ------------------------------------------

class OddsIterator implements Iterator<int> {  // Iterate over odd numbers
  List<int> _ints;
  int _index;

  OddsIterator(this._ints) {
    _index = -1;
  }

  bool moveNext() {
    while (++_index < _ints.length) {
      if (_ints[_index].isOdd)
        return true;
    }
    return false;
  }

  int get current => (_index < 0) ? null : _ints[_index];
}
like image 823
Gunnar Eketrapp Avatar asked May 14 '13 14:05

Gunnar Eketrapp


2 Answers

I see two immediate problems:

  1. iterator is a getter. The code shouldn't read Iterator<int> iterator() { ... }, it should be Iterator<int> get iterator { ... } instead.

  2. Your iterators are expecting the underlying integer lists, but you are passing in the wrapper. You probably want to construct your iterator like new OddsIterator(_ints), not like new OddsIterator(this).

Btw, Iterator is supposed to return null if you call current and you have already moved beyond the end.

like image 184
Ladicek Avatar answered Sep 26 '22 02:09

Ladicek


class Count extends Iterable with Iterator {
  Count([this.limit = 10]);
  int limit;
  int i = 0;

  @override
  int get current => i;

  @override
  bool moveNext() {
    i++;    
    return i <= limit;
  }

  @override
  Iterator get iterator => this;
}
like image 28
Branden Bobo Avatar answered Sep 23 '22 02:09

Branden Bobo