Single method
Returns the single element in the element, optionally matching a
condition
.
If condition
is omitted, Single will return the single value in this
enumerable. If the enumerable is empty, a EmptyEnumerableError is thrown.
If the enumerable contains more than one element, an OperationError is
thrown.
In this scenario, the Single function will short-circuit after iterating a maximum of two elements into the enumerable.
If condition
is supplied, Single will iterate over the entire
enumerable, applying the condition
function to each element. At the end
of the iteration, if a single element matches the condition
, that element
is returned. If no elements match the condition
, an ElementNotFoundError
is thrown. If more than one element matches the condition
, an
OperationError is thrown.
In this scenario, the Single function will short-circuit after finding a
second element that matches the condition
. In the worst-case scenario,
Single will iterate over the entire enumerable.
Implementation
T Single([Condition<T> condition]) {
final _iterator = this.iterator;
if (!_iterator.moveNext()) {
throw OperationError('The enumerable is empty.');
}
bool valueSet = false;
T value;
if (condition != null) {
do {
if (condition(_iterator.current)) {
if (valueSet)
throw OperationError(
'More than one element matches the condition.');
value = _iterator.current;
valueSet = true;
}
} while (_iterator.moveNext());
if (!valueSet) throw ElementNotFoundError();
return value;
}
do {
if (valueSet)
throw OperationError('More than one element exists in the enumerable.');
value = _iterator.current;
valueSet = true;
} while (_iterator.moveNext());
if (!valueSet) throw UnexpectedStateError();
return value;
}