Skip to content

Instantly share code, notes, and snippets.

@seaneagan
Created November 7, 2011 18:48
Show Gist options
  • Select an option

  • Save seaneagan/1345796 to your computer and use it in GitHub Desktop.

Select an option

Save seaneagan/1345796 to your computer and use it in GitHub Desktop.
Dart-iterable-methods
// mixin instead of a class ?
class CollectionImpl<E> implements Collection<E> {
Iterable _wrapped;
CollectionImpl(Iterable other) {
this._wrapped = other;
}
Iterator<E> iterator() => _wrapped.iterator();
int get count () {
final int count = 0;
for(final i in this) count++;
return count;
}
bool get empty () => !iterator().hasNext();
bool contains (E item) {
for(final i in this) {
if(item == i) { // i == item instead ?
return true;
}
return false;
}
}
bool containsIdentical (E item) {
for(final i in this) {
if(item === i) {
return true;
}
return false;
}
}
bool containsAll (Iterable<E> other) {
for(final i in other) {
if(!contains(i)) {
return false;
}
return true;
}
}
void forEach(void f(E item/*, int index, Iterable<E> self*/)) {
int i = 0;
for(final item in this) f(item/*, i++, this*/);
}
bool every(bool f(E item/*, int index, Iterable<E> self*/)) {
int i = 0;
for(final item in this) if(!f(item/*, i++, this*/)) return false;
return true;
}
bool some(bool f(E item/*, int index, Iterable<E> self*/)) {
int i = 0;
for(final item in this) if(f(item/*, i++, this*/)) return true;
return false;
}
void join([String separator = '']) {
String joined = '';
final iter = iterator();
bool hasNext = iter.hasNext();
while(hasNext) {
joined += iter.next().toString();
if(hasNext = iter.hasNext()) joined += separator;
}
return joined;
}
// Note: initialValue could be optional when E is assignable to T
// Need generic functions here (see http://code.google.com/p/dart/issues/detail?id=254)
/*T*/ reduce/*<T>*/(Dynamic/*T*/ f(/*T*/ previous, E current), [/*T*/ initialValue = null]) {
var/*T*/ previous = initialValue;
for(final item in this) previous = f(previous, current);
return previous;
}
Iterable<E> filter(FilterCallback<E> f) => new _FilterIterable(this, f);
// Need generic functions here
Iterable<Dynamic/*T*/> map/*<T>*/(MapCallback<E, Dynamic/*T*/> f) => new _MapIterable(this, f);
/** Compute the minimum of an iterable. Returns initialValue if empty. */
E min(Comparator<E> f, [E initialValue]) => reduce((prev, curr) => f(prev, curr) <= 0 ? prev : curr, initialValue);
/** Compute the maximum of an iterable. Returns initialValue if empty. */
E max(Comparator<E> f, [E initialValue]) => reduce((prev, curr) => f(prev, curr) >= 0 ? prev : curr, initialValue);
/** Orders an iterable by its values, or by a key selector. */
Iterable<E> sort(Comparator<E> comparator]) {
final result = new List.from(source);
sortBy(result, selector);
return result;
}
/** Sorts a list by its values, or by a key selector. */
// TODO(jmesserly): we probably don't want to call the key selector more than
// once for a given element. This would improve performance and the API
// contract could be stronger.
static void sortBy(List list, [NumericValueSelector selector = null]) {
if (selector != null) {
list.sort((x, y) => selector(x) - selector(y));
} else {
list.sort((x, y) => x - y);
}
}
/** Compute the sum of an iterable. Needs structural types to check for + operator */
E sum(E initialValue) {
Addable<E>
E operator + (E other);
// throw error if E does not support + operator
return reduce((E prev, E curr) => prev + curr, initialValue);
final iter = source.iterator();
}
class _FilterIterable<E> implements Iterable<E> {
Iterable<E> _source;
FilterCallback<E> _filter;
_FilterIterable(this._source, this._filter);
iterator() => new _FilterIterator(this);
}
class _FilterIterator<E> implements Iterator<E> {
_FilterIterable<E> _iterable;
Iterator<E> _iterator;
E _next;
bool _hasNext = true;
bool _mustFindNext = true;
int _index = 0;
_FilterIterator(this._iterable) {
_iterator = _iterable.iterator();
}
E next() {
_findNext();
_mustFindNext = true;
if(_hasNext) {
return _next;
}
// throw
}
bool hasNext() {_findNext(); return _hasNext;}
_findNext() {
while(_mustFindNext) {
if(!_iterator.hasNext()) {
_hasNext = false;
_mustFindNext = false;
}
else if(_iterable._filter(_next = _iterator.next()/*, _index++, _iterable._source*/)) _mustFindNext = false;
}
}
}
class _MapIterable<E, T> implements Iterable<T> {
Iterable<E> _source;
MapCallback<E, T> _map;
_MapIterable(this._source, this._map);
iterator() => new _MapIterator(this);
}
class _MapIterator<E, T> implements Iterator<T> {
_MapIterable<E, T> _iterable;
Iterator<E> _iterator;
int _index = 0;
_MapIterator(this._iterable) {
_iterator = _iterable.iterator();
}
T next() => _iterable._map(_iterator.next()/*, _index++, _iterable._source*/);
bool hasNext() => _iterator.hasNext();
}
class _UnionIterable<E> implements Iterable<E> {
final Iterable<E> _first, _second;
const _UnionIterable(this._first, this._second);
iterator() => new _UnionIterator(this);
}
class _UnionIterator<E> implements Iterator<E> {
final _UnionIterable<E> _iterable;
Iterator<E> _iterator;
bool _inFirst = true;
_UnionIterator(this._iterable) {
_iterator = _iterable._first.iterator();
}
E next() {
_updateIterator();
if(_iterator.hasNext()) return _iterator.next();
// throw
}
bool hasNext() {
_updateIterator();
return _iterator.hasNext();
}
void _updateIterator() {
if(_inFirst && !_iterator.hasNext()) {
_inFirst = false;
_iterator = _iterable._second.iterator();
}
}
typedef T MapCallback<E, T>(E item/*, int index, Iterable<E> self*/);
typedef bool FilterCallback<E>(E item/*, int index, Iterable<E> self*/);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment