blob: 72a02a944a4e79c93877ae14bfb038cff53928ca [file] [log] [blame]
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
part of quiver.iterables;
/**
* Returns an [Iterable] of [IndexedValue]s where the nth value holds the nth
* element of [iterable] and its index.
*/
Iterable<IndexedValue> enumerate(Iterable iterable) =>
new EnumerateIterable(iterable);
class IndexedValue<V> {
final int index;
final V value;
IndexedValue(this.index, this.value);
operator ==(o) => o is IndexedValue && o.index == index && o.value == value;
int get hashCode => index * 31 + value.hashCode;
String toString() => '($index, $value)';
}
/**
* An [Iterable] of [IndexedValue]s where the nth value holds the nth
* element of [iterable] and its index. See [enumerate].
*/
// This was inspired by MappedIterable internal to Dart collections.
class EnumerateIterable<V> extends IterableBase<IndexedValue<V>> {
final Iterable<V> _iterable;
EnumerateIterable(this._iterable);
Iterator<IndexedValue<V>> get iterator =>
new EnumerateIterator<V>(_iterable.iterator);
// Length related functions are independent of the mapping.
int get length => _iterable.length;
bool get isEmpty => _iterable.isEmpty;
// Index based lookup can be done before transforming.
IndexedValue<V> get first => new IndexedValue<V>(0, _iterable.first);
IndexedValue<V> get last => new IndexedValue<V>(length - 1, _iterable.last);
IndexedValue<V> get single => new IndexedValue<V>(0, _iterable.single);
IndexedValue<V> elementAt(int index) =>
new IndexedValue<V>(index, _iterable.elementAt(index));
}
/** The [Iterator] returned by [EnumerateIterable.iterator]. */
class EnumerateIterator<V> extends Iterator<IndexedValue<V>> {
final Iterator<V> _iterator;
int _index = 0;
IndexedValue<V> _current;
EnumerateIterator(this._iterator);
IndexedValue<V> get current => _current;
bool moveNext() {
if (_iterator.moveNext()) {
_current = new IndexedValue(_index++, _iterator.current);
return true;
}
_current = null;
return false;
}
}