SingleOrDefault method

T SingleOrDefault (T defaultValue, [ Condition<T> condition ])

Returns the single element in the element, optionally matching a condition, or a defaultValue if no such element exists.

If condition is omitted, SingleOrDefault will return the single value in this enumerable. If the enumerable is empty, the value specified by defaultValue is returned instead. If the enumerable contains more than one element, an OperationError is thrown.

In this scenario, the SingleOrDefault function will short-circuit after iterating a maximum of two elements into the enumerable.

If condition is supplied, SingleOrDefault 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, the value specified by defaultValue is returned instead. If more than one element matches the condition, an OperationError is thrown.

In this scenario, the SingleOrDefault function will short-circuit after finding a second element that matches the condition. In the worst-case scenario, SingleOrDefault will iterate over the entire enumerable.

Implementation

T SingleOrDefault(T defaultValue, [Condition<T> condition]) {
  final _iterator = this.iterator;

  if (!_iterator.moveNext()) return defaultValue;

  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) return defaultValue;

    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;
}