Dart DocumentationobserveObservableList<E>

ObservableList<E> class

Represents an observable list of model values. If any items are added, removed, or replaced, then observers that are listening to changes will be notified.

class ObservableList<E> extends _ListBaseWorkaround with ObservableMixin
   implements List<E> {
 List<ListChangeRecord> _records;

 /** The inner [List<E>] with the actual storage. */
 final List<E> _list;

 /**
  * Creates an observable list of the given [length].
  *
  * If no [length] argument is supplied an extendable list of
  * length 0 is created.
  *
  * If a [length] argument is supplied, a fixed size list of that
  * length is created.
  */
 ObservableList([int length])
     : _list = length != null ? new List<E>(length) : <E>[];

 /**
  * Creates an observable list with the elements of [other]. The order in
  * the list will be the order provided by the iterator of [other].
  */
 factory ObservableList.from(Iterable<E> other) =>
     new ObservableList<E>()..addAll(other);

 int get length => _list.length;

 set length(int value) {
   int len = _list.length;
   if (len == value) return;

   // Produce notifications if needed
   if (hasObservers) {
     if (value < len) {
       // Remove items, then adjust length. Note the reverse order.
       _recordChange(new ListChangeRecord(value, removedCount: len - value));
     } else {
       // Adjust length then add items
       _recordChange(new ListChangeRecord(len, addedCount: value - len));
     }
   }

   _list.length = value;
 }

 E operator [](int index) => _list[index];

 void operator []=(int index, E value) {
   var oldValue = _list[index];
   if (hasObservers) {
     _recordChange(new ListChangeRecord(index, addedCount: 1,
                                               removedCount: 1));
   }
   _list[index] = value;
 }

 // The following methods are here so that we can provide nice change events.

 void setAll(int index, Iterable<E> iterable) {
   if (iterable is! List && iterable is! Set) {
     iterable = iterable.toList();
   }
   var len = iterable.length;
   _list.setAll(index, iterable);
   if (hasObservers && len > 0) {
     _recordChange(
         new ListChangeRecord(index, addedCount: len, removedCount: len));
   }
 }

 void add(E value) {
   int len = _list.length;
   if (hasObservers) {
     _recordChange(new ListChangeRecord(len, addedCount: 1));
   }

   _list.add(value);
 }

 void addAll(Iterable<E> iterable) {
   int len = _list.length;
   _list.addAll(iterable);
   int added = _list.length - len;
   if (hasObservers && added > 0) {
     _recordChange(new ListChangeRecord(len, addedCount: added));
   }
 }

 bool remove(Object element) {
   for (int i = 0; i < this.length; i++) {
     if (this[i] == element) {
       removeRange(i, 1);
       return true;
     }
   }
   return false;
 }

 void removeRange(int start, int end) {
   _rangeCheck(start, end);
   int length = end - start;
   _list.setRange(start, this.length - length, this, end);

   int len = _list.length;
   _list.length -= length;
   if (hasObservers && length > 0) {
     _recordChange(new ListChangeRecord(start, removedCount: length));
   }
 }

 void insertAll(int index, Iterable<E> iterable) {
   if (index < 0 || index > length) {
     throw new RangeError.range(index, 0, length);
   }
   // TODO(floitsch): we can probably detect more cases.
   if (iterable is! List && iterable is! Set) {
     iterable = iterable.toList();
   }
   int insertionLength = iterable.length;
   // There might be errors after the length change, in which case the list
   // will end up being modified but the operation not complete. Unless we
   // always go through a "toList" we can't really avoid that.
   int len = _list.length;
   _list.length += insertionLength;

   _list.setRange(index + insertionLength, this.length, this, index);
   _list.setAll(index, iterable);

   if (hasObservers && insertionLength > 0) {
     _recordChange(new ListChangeRecord(index, addedCount: insertionLength));
   }
 }

 void insert(int index, E element) {
   if (index < 0 || index > length) {
     throw new RangeError.range(index, 0, length);
   }
   if (index == length) {
     add(element);
     return;
   }
   // We are modifying the length just below the is-check. Without the check
   // Array.copy could throw an exception, leaving the list in a bad state
   // (with a length that has been increased, but without a new element).
   if (index is! int) throw new ArgumentError(index);
   _list.length++;
   _list.setRange(index + 1, length, this, index);
   if (hasObservers) {
     _recordChange(new ListChangeRecord(index, addedCount: 1));
   }
   _list[index] = element;
 }


 E removeAt(int index) {
   E result = this[index];
   removeRange(index, index + 1);
   return result;
 }

 void _rangeCheck(int start, int end) {
   if (start < 0 || start > this.length) {
     throw new RangeError.range(start, 0, this.length);
   }
   if (end < start || end > this.length) {
     throw new RangeError.range(end, start, this.length);
   }
 }

 void _recordChange(ListChangeRecord record) {
   if (_records == null) {
     _records = [];
     queueChangeRecords(_summarizeRecords);
   }
   _records.add(record);
 }

 /**
  * We need to summarize change records. Consumers of these records want to
  * apply the batch sequentially, and ensure that they can find inserted
  * items by looking at that position in the list. This property does not
  * hold in our record-as-you-go records. Consider:
  *
  *     var model = toObservable(['a', 'b']);
  *     model.removeAt(1);
  *     model.insertAll(0, ['c', 'd', 'e']);
  *     model.removeRange(1, 3);
  *     model.insert(1, 'f');
  *
  * Here, we inserted some records and then removed some of them.
  * If someone processed these records naively, they would "play back" the
  * insert incorrectly, because those items will be shifted.
  *
  * We summarize changes using a straightforward technique:
  * Simulate the moves and use the final item positions to synthesize a
  * new list of changes records. This has the advantage of not depending
  * on the actual *values*, so we don't need to perform N^2 edit
  */
 // TODO(jmesserly): there's probably something smarter here, but this
 // algorithm is pretty simple. It has complexity equivalent to the original
 // list modifications.
 // One simple idea: we can simply update the index map as we do the operations
 // to the list, then produce the records at the end.
 void _summarizeRecords() {
   int oldLength = length;
   for (var r in _records) {
     oldLength += r.removedCount - r.addedCount;
   }

   if (length != oldLength) {
     notifyPropertyChange(const Symbol('length'), oldLength, length);
   }

   if (_records.length == 1) {
     notifyChange(_records[0]);
     _records = null;
     return;
   }

   var items = [];
   for (int i = 0; i < oldLength; i++) items.add(i);
   for (var r in _records) {
     items.removeRange(r.index, r.index + r.removedCount);

     // Represent inserts with -1.
     items.insertAll(r.index, new List.filled(r.addedCount, -1));
   }
   assert(items.length == length);

   _records = null;

   int index = 0;
   int offset = 0;
   while (index < items.length) {
     // Skip unchanged items.
     while (index < items.length && items[index] == index + offset) {
       index++;
     }

     // Find inserts
     int startIndex = index;
     while (index < items.length && items[index] == -1) {
       index++;
     }

     int added = index - startIndex;

     // Use the delta between our actual and expected position to determine
     // how much was removed.
     int actualItem = index < items.length ? items[index] : oldLength;
     int expectedItem = startIndex + offset;

     int removed = actualItem - expectedItem;

     if (added > 0 || removed > 0) {
       notifyChange(new ListChangeRecord(startIndex, addedCount: added,
           removedCount: removed));
     }

     offset += removed - added;
   }
 }
}

Extends

ListBase<dynamic> > _ListBaseWorkaround > _ListBaseWorkaround_ObservableMixin > ObservableList<E>

Implements

List<E>

Constructors

new ObservableList([int length]) #

Creates an observable list of the given length.

If no length argument is supplied an extendable list of length 0 is created.

If a length argument is supplied, a fixed size list of that length is created.

ObservableList([int length])
   : _list = length != null ? new List<E>(length) : <E>[];

factory ObservableList.from(Iterable<E> other) #

Creates an observable list with the elements of other. The order in the list will be the order provided by the iterator of other.

factory ObservableList.from(Iterable<E> other) =>
   new ObservableList<E>()..addAll(other);

Properties

final Stream<List<ChangeRecord>> changes #

The stream of change records to this object.

Changes should be delivered in asynchronous batches by calling queueChangeRecords.

deliverChangeRecords can be called to force delivery.

docs inherited from Observable
Stream<List<ChangeRecord>> get changes {
 if (_broadcastController == null) {
   _broadcastController =
       new StreamController<List<ChangeRecord>>.broadcast(sync: true);
 }
 return _broadcastController.stream;
}

final E first #

inherited from ListBase

Returns the first element.

If this is empty throws a StateError. Otherwise this method is equivalent to this.elementAt(0)

docs inherited from Iterable<E>
E get first {
 if (length == 0) throw new StateError("No elements");
 return this[0];
}

final bool hasObservers #

True if this object has any observers, and should call notifyPropertyChange for changes.

bool get hasObservers => _broadcastController != null &&
                        _broadcastController.hasListener;

final bool isEmpty #

inherited from ListBase

Returns true if there is no element in this collection.

docs inherited from Iterable<E>
bool get isEmpty => length == 0;

final bool isNotEmpty #

inherited from ListBase

Returns true if there is at least one element in this collection.

docs inherited from Iterable<E>
bool get isNotEmpty => !isEmpty;

final Iterator<E> iterator #

inherited from ListBase

Returns an Iterator that iterates over this Iterable object.

docs inherited from Iterable<E>
Iterator<E> get iterator => new ListIterator<E>(this);

final E last #

inherited from ListBase

Returns the last element.

If this is empty throws a StateError.

docs inherited from Iterable<E>
E get last {
 if (length == 0) throw new StateError("No elements");
 return this[length - 1];
}

int get length #

Returns the number of elements in the list.

The valid indices for a list are 0 through length - 1.

docs inherited from List<E>
int get length => _list.length;

dynamic set length(int value) #

Changes the length of the list. If newLength is greater than the current length, entries are initialized to null.

Throws an UnsupportedError if the list is not extendable.

docs inherited from List<E>
set length(int value) {
 int len = _list.length;
 if (len == value) return;

 // Produce notifications if needed
 if (hasObservers) {
   if (value < len) {
     // Remove items, then adjust length. Note the reverse order.
     _recordChange(new ListChangeRecord(value, removedCount: len - value));
   } else {
     // Adjust length then add items
     _recordChange(new ListChangeRecord(len, addedCount: value - len));
   }
 }

 _list.length = value;
}

final Iterable<E> reversed #

inherited from ListBase

Returns an Iterable of the elements of this List in reverse order.

docs inherited from List<E>
Iterable<E> get reversed => new ReversedListIterable(this);

final E single #

inherited from ListBase

Returns the single element in this.

If this is empty or has more than one element throws a StateError.

docs inherited from Iterable<E>
E get single {
 if (length == 0) throw new StateError("No elements");
 if (length > 1) throw new StateError("Too many elements");
 return this[0];
}

Operators

E operator [](int index) #

Returns the element at the given index in the list or throws an RangeError if index is out of bounds.

docs inherited from List<E>
E operator [](int index) => _list[index];

void operator []=(int index, E value) #

Sets the entry at the given index in the list to value.

Throws an RangeError if index is out of bounds.

docs inherited from List<E>
void operator []=(int index, E value) {
 var oldValue = _list[index];
 if (hasObservers) {
   _recordChange(new ListChangeRecord(index, addedCount: 1,
                                             removedCount: 1));
 }
 _list[index] = value;
}

Methods

void add(E value) #

Adds value at the end of the list, extending the length by one.

Throws an UnsupportedError if the list is not extendable.

docs inherited from List<E>
void add(E value) {
 int len = _list.length;
 if (hasObservers) {
   _recordChange(new ListChangeRecord(len, addedCount: 1));
 }

 _list.add(value);
}

void addAll(Iterable<E> iterable) #

Appends all elements of the iterable to the end of this list.

Extends the length of the list by the number of elements in iterable. Throws an UnsupportedError if this list is not extensible.

docs inherited from List<E>
void addAll(Iterable<E> iterable) {
 int len = _list.length;
 _list.addAll(iterable);
 int added = _list.length - len;
 if (hasObservers && added > 0) {
   _recordChange(new ListChangeRecord(len, addedCount: added));
 }
}

bool any(bool test(E element)) #

inherited from ListBase

Returns true if one element of this collection satisfies the predicate test. Returns false otherwise.

docs inherited from Iterable<E>
bool any(bool test(E element)) {
 int length = this.length;
 for (int i = 0; i < length; i++) {
   if (test(this[i])) return true;
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 return false;
}

Map<int, E> asMap() #

inherited from ListBase

Returns an unmodifiable Map view of this.

It has the indices of this list as keys, and the corresponding elements as values. The [Map.keys] [Iterable] will iterate the indices of this list in numerical order.

docs inherited from List<E>
Map<int, E> asMap() {
 return new ListMapView(this);
}

void clear() #

inherited from ListBase

Removes all elements in the list.

The length of the list becomes zero.

Throws an UnsupportedError, and retains all elements, if the length of the list cannot be changed.

docs inherited from List<E>
void clear() { this.length = 0; }

bool contains(Object element) #

inherited from ListBase

Check whether the collection contains an element equal to element.

docs inherited from Iterable<E>
bool contains(Object element) {
 int length = this.length;
 for (int i = 0; i < length; i++) {
   if (this[i] == element) return true;
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 return false;
}

E elementAt(int index) #

inherited from ListBase

Returns the indexth element.

If this has fewer than index elements throws a RangeError.

Note: if this does not have a deterministic iteration order then the function may simply return any element without any iteration if there are at least index elements in this.

docs inherited from Iterable<E>
E elementAt(int index) => this[index];

bool every(bool test(E element)) #

inherited from ListBase

Returns true if every elements of this collection satisify the predicate test. Returns false otherwise.

docs inherited from Iterable<E>
bool every(bool test(E element)) {
 int length = this.length;
 for (int i = 0; i < length; i++) {
   if (!test(this[i])) return false;
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 return true;
}

Iterable expand(Iterable f(E element)) #

inherited from ListBase

Expand each element of this Iterable into zero or more elements.

The resulting Iterable will run through the elements returned by f for each element of this, in order.

The returned Iterable is lazy, and will call f for each element of this every time it's iterated.

docs inherited from Iterable<E>
Iterable expand(Iterable f(E element)) =>
   new ExpandIterable<E, dynamic>(this, f);

void fillRange(int start, int end, [E fill]) #

inherited from ListBase

Sets the elements in the range start to end exclusive to the given fillValue.

It is an error if start.. end is not a valid range pointing into the this.

docs inherited from List<E>
void fillRange(int start, int end, [E fill]) {
 _rangeCheck(start, end);
 for (int i = start; i < end; i++) {
   this[i] = fill;
 }
}

dynamic firstWhere(bool test(E element), {Object orElse()}) #

inherited from ListBase

Returns the first element that satisfies the given predicate test.

If none matches, the result of invoking the orElse function is returned. By default, when orElse is null, a StateError is thrown.

docs inherited from Iterable<E>
dynamic firstWhere(bool test(E element), { Object orElse() }) {
 int length = this.length;
 for (int i = 0; i < length; i++) {
   E element = this[i];
   if (test(element)) return element;
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 if (orElse != null) return orElse();
 throw new StateError("No matching element");
}

dynamic fold(initialValue, combine(previousValue, E element)) #

inherited from ListBase

Reduces a collection to a single value by iteratively combining each element of the collection with an existing value using the provided function.

Use initialValue as the initial value, and the function combine to create a new value from the previous one and an element.

Example of calculating the sum of an iterable:

iterable.fold(0, (prev, element) => prev + element);
docs inherited from Iterable<E>
fold(var initialValue, combine(var previousValue, E element)) {
 var value = initialValue;
 int length = this.length;
 for (int i = 0; i < length; i++) {
   value = combine(value, this[i]);
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 return value;
}

void forEach(void action(E element)) #

inherited from ListBase

Applies the function f to each element of this collection.

docs inherited from Iterable<E>
void forEach(void action(E element)) {
 int length = this.length;
 for (int i = 0; i < length; i++) {
   action(this[i]);
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
}

Iterable<E> getRange(int start, int end) #

inherited from ListBase

Returns an Iterable that iterates over the elements in the range start to end exclusive. The result of this function is backed by this.

It is an error if end is before start.

It is an error if the start and end are not valid ranges at the time of the call to this method. The returned Iterable behaves similar to skip(start).take(end - start). That is, it will not throw exceptions if this changes size.

Example:

var list = [1, 2, 3, 4, 5];
var range = list.getRange(1, 4);
print(range.join(', '));  // => 2, 3, 4
list.length = 3;
print(range.join(', '));  // => 2, 3
docs inherited from List<E>
Iterable<E> getRange(int start, int end) {
 _rangeCheck(start, end);
 return new SubListIterable(this, start, end);
}

int indexOf(Object element, [int startIndex = 0]) #

inherited from ListBase

Returns the first index of element in the list.

Searches the list from index start to the length of the list. The first time an element e is encountered so that e == element, the index of e is returned. Returns -1 if element is not found.

docs inherited from List<E>
int indexOf(Object element, [int startIndex = 0]) {
 if (startIndex >= this.length) {
   return -1;
 }
 if (startIndex < 0) {
   startIndex = 0;
 }
 for (int i = startIndex; i < this.length; i++) {
   if (this[i] == element) {
     return i;
   }
 }
 return -1;
}

void insert(int index, E element) #

Inserts the element at position index in the list.

This increases the length of the list by one and shifts all elements at or after the index towards the end of the list.

It is an error if the index does not point inside the list or at the position after the last element.

docs inherited from List<E>
void insert(int index, E element) {
 if (index < 0 || index > length) {
   throw new RangeError.range(index, 0, length);
 }
 if (index == length) {
   add(element);
   return;
 }
 // We are modifying the length just below the is-check. Without the check
 // Array.copy could throw an exception, leaving the list in a bad state
 // (with a length that has been increased, but without a new element).
 if (index is! int) throw new ArgumentError(index);
 _list.length++;
 _list.setRange(index + 1, length, this, index);
 if (hasObservers) {
   _recordChange(new ListChangeRecord(index, addedCount: 1));
 }
 _list[index] = element;
}

void insertAll(int index, Iterable<E> iterable) #

Inserts all elements of iterable at position index in the list.

This increases the length of the list by the length of iterable and shifts all later elements towards the end of the list.

It is an error if the index does not point inside the list or at the position after the last element.

docs inherited from List<E>
void insertAll(int index, Iterable<E> iterable) {
 if (index < 0 || index > length) {
   throw new RangeError.range(index, 0, length);
 }
 // TODO(floitsch): we can probably detect more cases.
 if (iterable is! List && iterable is! Set) {
   iterable = iterable.toList();
 }
 int insertionLength = iterable.length;
 // There might be errors after the length change, in which case the list
 // will end up being modified but the operation not complete. Unless we
 // always go through a "toList" we can't really avoid that.
 int len = _list.length;
 _list.length += insertionLength;

 _list.setRange(index + insertionLength, this.length, this, index);
 _list.setAll(index, iterable);

 if (hasObservers && insertionLength > 0) {
   _recordChange(new ListChangeRecord(index, addedCount: insertionLength));
 }
}

String join([String separator = ""]) #

inherited from ListBase

Converts each element to a String and concatenates the strings.

Converts each element to a String by calling Object.toString on it. Then concatenates the strings, optionally separated by the separator string.

docs inherited from Iterable<E>
String join([String separator = ""]) {
 int length = this.length;
 if (!separator.isEmpty) {
   if (length == 0) return "";
   String first = "${this[0]}";
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
   StringBuffer buffer = new StringBuffer(first);
   for (int i = 1; i < length; i++) {
     buffer.write(separator);
     buffer.write(this[i]);
     if (length != this.length) {
       throw new ConcurrentModificationError(this);
     }
   }
   return buffer.toString();
 } else {
   StringBuffer buffer = new StringBuffer();
   for (int i = 0; i < length; i++) {
     buffer.write(this[i]);
     if (length != this.length) {
       throw new ConcurrentModificationError(this);
     }
   }
   return buffer.toString();
 }
}

int lastIndexOf(Object element, [int startIndex]) #

inherited from ListBase

Returns the last index in the list a of the given element, starting the search at index startIndex to 0. Returns -1 if element is not found.

int lastIndexOf(Object element, [int startIndex]) {
 if (startIndex == null) {
   startIndex = this.length - 1;
 } else {
   if (startIndex < 0) {
     return -1;
   }
   if (startIndex >= this.length) {
     startIndex = this.length - 1;
   }
 }
 for (int i = startIndex; i >= 0; i--) {
   if (this[i] == element) {
     return i;
   }
 }
 return -1;
}

dynamic lastWhere(bool test(E element), {Object orElse()}) #

inherited from ListBase

Returns the last element that satisfies the given predicate test.

If none matches, the result of invoking the orElse function is returned. By default, when orElse is null, a StateError is thrown.

docs inherited from Iterable<E>
dynamic lastWhere(bool test(E element), { Object orElse() }) {
 int length = this.length;
 for (int i = length - 1; i >= 0; i--) {
   E element = this[i];
   if (test(element)) return element;
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 if (orElse != null) return orElse();
 throw new StateError("No matching element");
}

Iterable map(f(E element)) #

inherited from ListBase

Returns a lazy Iterable where each element e of this is replaced by the result of f(e).

This method returns a view of the mapped elements. As long as the returned Iterable is not iterated over, the supplied function f will not be invoked. The transformed elements will not be cached. Iterating multiple times over the the returned Iterable will invoke the supplied function f multiple times on the same element.

docs inherited from Iterable<E>
Iterable map(f(E element)) => new MappedListIterable(this, f);

void notifyChange(ChangeRecord record) #

Notify observers of a change. For most objects notifyPropertyChange is more convenient, but collections sometimes deliver other types of changes such as a ListChangeRecord.

void notifyChange(ChangeRecord record) {
 if (!hasObservers) return;

 if (_changes == null) {
   _changes = [];
   queueChangeRecords(_deliverChanges);
 }
 _changes.add(record);
}

dynamic notifyPropertyChange(Symbol field, Object oldValue, Object newValue) #

Notify that the field name of this object has been changed.

The oldValue and newValue are also recorded. If the two values are identical, no change will be recorded.

For convenience this returns newValue. This makes it easy to use in a setter:

var _myField;
get myField => _myField;
set myField(value) {
  _myField = notifyPropertyChange(
      const Symbol('myField'), _myField, value);
}
notifyPropertyChange(Symbol field, Object oldValue, Object newValue) {
 if (hasObservers && !identical(oldValue, newValue)) {
   notifyChange(new PropertyChangeRecord(field));
 }
 return newValue;
}

E reduce(E combine(E previousValue, E element)) #

inherited from ListBase

Reduces a collection to a single value by iteratively combining elements of the collection using the provided function.

Example of calculating the sum of an iterable:

iterable.reduce((value, element) => value + element);
docs inherited from Iterable<E>
E reduce(E combine(E previousValue, E element)) {
 if (length == 0) throw new StateError("No elements");
 E value = this[0];
 for (int i = 1; i < length; i++) {
   value = combine(value, this[i]);
 }
 return value;
}

bool remove(Object element) #

Removes value from the list. Returns true if value was in the list. Returns false otherwise. The method has no effect if value value was not in the list.

docs inherited from List<E>
bool remove(Object element) {
 for (int i = 0; i < this.length; i++) {
   if (this[i] == element) {
     removeRange(i, 1);
     return true;
   }
 }
 return false;
}

E removeAt(int index) #

Removes the element at position index from the list.

This reduces the length of this by one and moves all later elements down by one position.

Returns the removed element.

Throws an ArgumentError if index is not an int.

Throws an RangeError if the index does not point inside the list.

Throws an UnsupportedError, and doesn't remove the element, if the length of this cannot be changed.

docs inherited from List<E>
E removeAt(int index) {
 E result = this[index];
 removeRange(index, index + 1);
 return result;
}

E removeLast() #

inherited from ListBase

Pops and returns the last element of the list. Throws a UnsupportedError if the length of the list cannot be changed.

docs inherited from List<E>
E removeLast() {
 if (length == 0) {
   throw new StateError("No elements");
 }
 E result = this[length - 1];
 length--;
 return result;
}

void removeRange(int start, int end) #

Removes the elements in the range start to end exclusive.

It is an error if start.. end is not a valid range pointing into the this.

docs inherited from List<E>
void removeRange(int start, int end) {
 _rangeCheck(start, end);
 int length = end - start;
 _list.setRange(start, this.length - length, this, end);

 int len = _list.length;
 _list.length -= length;
 if (hasObservers && length > 0) {
   _recordChange(new ListChangeRecord(start, removedCount: length));
 }
}

void removeWhere(bool test(E element)) #

inherited from ListBase

Removes all elements of this list that satisfy test.

An elements e satisfies test if test(e) is true.

docs inherited from List<E>
void removeWhere(bool test(E element)) {
 _filter(this, test, false);
}

void replaceRange(int start, int end, Iterable<E> newContents) #

inherited from ListBase

Removes the elements in the range start to end exclusive and replaces them with the contents of the iterable.

It is an error if start.. end is not a valid range pointing into the this.

Example:

var list = [1, 2, 3, 4, 5];
list.replaceRange(1, 3, [6, 7, 8, 9]);
print(list);  // [1, 6, 7, 8, 9, 4, 5]
docs inherited from List<E>
void replaceRange(int start, int end, Iterable<E> newContents) {
 // TODO(floitsch): Optimize this.
 removeRange(start, end);
 insertAll(start, newContents);
}

void retainWhere(bool test(E element)) #

inherited from ListBase

Removes all elements of this list that fail to satisfy test.

An elements e satisfies test if test(e) is true.

docs inherited from List<E>
void retainWhere(bool test(E element)) {
 _filter(this, test, true);
}

void setAll(int index, Iterable<E> iterable) #

Overwrites elements of this with the elemenst of iterable starting at position index in the list.

This operation does not increase the length of this.

It is an error if the index does not point inside the list or at the position after the last element.

It is an error if the iterable is longer than length - index.

docs inherited from List<E>
void setAll(int index, Iterable<E> iterable) {
 if (iterable is! List && iterable is! Set) {
   iterable = iterable.toList();
 }
 var len = iterable.length;
 _list.setAll(index, iterable);
 if (hasObservers && len > 0) {
   _recordChange(
       new ListChangeRecord(index, addedCount: len, removedCount: len));
 }
}

void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) #

inherited from ListBase

Copies the elements of iterable, skipping the skipCount first elements, into the range start to end exclusive of this.

If start equals end and start.. end represents a legal range, this method has no effect.

It is an error if start.. end is not a valid range pointing into the this.

It is an error if the iterable does not have enough elements after skipping skipCount elements.

Example:

var list = [1, 2, 3, 4];
var list2 = [5, 6, 7, 8, 9];
list.setRange(1, 3, list2, 3);
print(list);  // => [1, 8, 9, 4]
docs inherited from List<E>
void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
 _rangeCheck(start, end);
 int length = end - start;
 if (length == 0) return;

 if (skipCount < 0) throw new ArgumentError(skipCount);

 List otherList;
 int otherStart;
 // TODO(floitsch): Make this accept more.
 if (iterable is List) {
   otherList = iterable;
   otherStart = skipCount;
 } else {
   otherList = iterable.skip(skipCount).toList(growable: false);
   otherStart = 0;
 }
 if (otherStart + length > otherList.length) {
   throw new StateError("Not enough elements");
 }
 if (otherStart < start) {
   // Copy backwards to ensure correct copy if [from] is this.
   for (int i = length - 1; i >= 0; i--) {
     this[start + i] = otherList[otherStart + i];
   }
 } else {
   for (int i = 0; i < length; i++) {
     this[start + i] = otherList[otherStart + i];
   }
 }
}

E singleWhere(bool test(E element)) #

inherited from ListBase

Returns the single element that satisfies test. If no or more than one element match then a StateError is thrown.

docs inherited from Iterable<E>
E singleWhere(bool test(E element)) {
 int length = this.length;
 E match = null;
 bool matchFound = false;
 for (int i = 0; i < length; i++) {
   E element = this[i];
   if (test(element)) {
     if (matchFound) {
       throw new StateError("More than one matching element");
     }
     matchFound = true;
     match = element;
   }
   if (length != this.length) {
     throw new ConcurrentModificationError(this);
   }
 }
 if (matchFound) return match;
 throw new StateError("No matching element");
}

Iterable<E> skip(int count) #

inherited from ListBase

Returns an Iterable that skips the first n elements.

If this has fewer than n elements, then the resulting Iterable will be empty.

It is an error if n is negative.

docs inherited from Iterable<E>
Iterable<E> skip(int count) => new SubListIterable(this, count, null);

Iterable<E> skipWhile(bool test(E element)) #

inherited from ListBase

Returns an Iterable that skips elements while test is satisfied.

The filtering happens lazily. Every new Iterator of the returned Iterable iterates over all elements of this.

As long as the iterator's elements satisfy test they are discarded. Once an element does not satisfy the test the iterator stops testing and uses every later element unconditionally. That is, the elements of the returned Iterable are the elements of this starting from the first element that does not satisfy test.

docs inherited from Iterable<E>
Iterable<E> skipWhile(bool test(E element)) {
 return new SkipWhileIterable<E>(this, test);
}

void sort([int compare(E a, E b)]) #

inherited from ListBase

Sorts the list according to the order specified by the compare function.

The compare function must act as a Comparator.

The default List implementations use Comparable.compare if compare is omitted.

docs inherited from List<E>
void sort([int compare(E a, E b)]) {
 if (compare == null) {
   var defaultCompare = Comparable.compare;
   compare = defaultCompare;
 }
 Sort.sort(this, compare);
}

List<E> sublist(int start, [int end]) #

inherited from ListBase

Returns a new list containing the elements from start to end.

If end is omitted, the length of this is used.

It is an error if start or end are not indices into this, or if end is before start.

docs inherited from List<E>
List<E> sublist(int start, [int end]) {
 if (end == null) end = length;
 _rangeCheck(start, end);
 int length = end - start;
 List<E> result = new List<E>()..length = length;
 for (int i = 0; i < length; i++) {
   result[i] = this[start + i];
 }
 return result;
}

Iterable<E> take(int count) #

inherited from ListBase

Returns an Iterable with at most n elements.

The returned Iterable may contain fewer than n elements, if this contains fewer than n elements.

It is an error if n is negative.

docs inherited from Iterable<E>
Iterable<E> take(int count) => new SubListIterable(this, 0, count);

Iterable<E> takeWhile(bool test(E element)) #

inherited from ListBase

Returns an Iterable that stops once test is not satisfied anymore.

The filtering happens lazily. Every new Iterator of the returned Iterable will start iterating over the elements of this.

When the iterator encounters an element e that does not satisfy test, it discards e and moves into the finished state. That is, it will not ask or provide any more elements.

docs inherited from Iterable<E>
Iterable<E> takeWhile(bool test(E element)) {
 return new TakeWhileIterable<E>(this, test);
}

List<E> toList({bool growable: true}) #

inherited from ListBase

Creates a List containing the elements of this Iterable.

The elements will be in iteration order. The list is fixed-length if growable is false.

docs inherited from Iterable<E>
List<E> toList({ bool growable: true }) {
 List<E> result;
 if (growable) {
   result = new List<E>()..length = length;
 } else {
   result = new List<E>(length);
 }
 for (int i = 0; i < length; i++) {
   result[i] = this[i];
 }
 return result;
}

Set<E> toSet() #

inherited from ListBase

Creates a Set containing the elements of this Iterable.

docs inherited from Iterable<E>
Set<E> toSet() {
 Set<E> result = new Set<E>();
 for (int i = 0; i < length; i++) {
   result.add(this[i]);
 }
 return result;
}

String toString() #

inherited from ListBase

Returns a string representation of this object.

docs inherited from Object
String toString() => ToString.iterableToString(this);

Iterable<E> where(bool test(E element)) #

inherited from ListBase

Returns a lazy Iterable with all elements that satisfy the predicate test.

This method returns a view of the mapped elements. As long as the returned Iterable is not iterated over, the supplied function test will not be invoked. Iterating will not cache results, and thus iterating multiple times over the the returned Iterable will invoke the supplied function test multiple times on the same element.

docs inherited from Iterable<E>
Iterable<E> where(bool test(E element)) => new WhereIterable<E>(this, test);