public static TSource First <TSource>(this IEnumerable <TSource> source) { if (source == null) { throw Error.ArgumentNull("source"); } IPartition <TSource> partition = source as IPartition <TSource>; if (partition != null) { bool found; TSource first = partition.TryGetFirst(out found); if (found) { return(first); } } else { IList <TSource> list = source as IList <TSource>; if (list != null) { if (list.Count > 0) { return(list[0]); } } else { using (IEnumerator <TSource> e = source.GetEnumerator()) { if (e.MoveNext()) { return(e.Current); } } } } throw Error.NoElements(); }
public static decimal Average(this IEnumerable <decimal> source) { if (source == null) { throw Error.ArgumentNull("source"); } using (IEnumerator <decimal> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } decimal sum = e.Current; long count = 1; while (e.MoveNext()) { sum += e.Current; ++count; } return(sum / count); } }
public static float Max(this IEnumerable <float> source) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } float value; using (IEnumerator <float> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = e.Current; while (float.IsNaN(value)) { if (!e.MoveNext()) { return(value); } value = e.Current; } while (e.MoveNext()) { float x = e.Current; if (x > value) { value = x; } } } return(value); }
private static async ValueTask <IList <TSource> > ExtremaBy <TSource, TKey>(IAsyncEnumerable <TSource> source, Func <TSource, CancellationToken, ValueTask <TKey> > keySelector, Func <TKey, TKey, int> compare, CancellationToken cancellationToken) { var result = new List <TSource>(); await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) { if (!await e.MoveNextAsync()) { throw Error.NoElements(); } var current = e.Current; var resKey = await keySelector(current, cancellationToken).ConfigureAwait(false); result.Add(current); while (await e.MoveNextAsync()) { var cur = e.Current; var key = await keySelector(cur, cancellationToken).ConfigureAwait(false); var cmp = compare(key, resKey); if (cmp == 0) { result.Add(cur); } else if (cmp > 0) { result = new List <TSource> { cur }; resKey = key; } } } return(result); }
public static TSource Last <TSource>(this IEnumerable <TSource> source) { if (source == null) { throw Error.ArgumentNull("source"); } IPartition <TSource> partition = source as IPartition <TSource>; if (partition != null) { return(partition.Last()); } IList <TSource> list = source as IList <TSource>; if (list != null) { int count = list.Count; if (count > 0) { return(list[count - 1]); } } else { using (IEnumerator <TSource> e = source.GetEnumerator()) { if (e.MoveNext()) { TSource result; do { result = e.Current; } while (e.MoveNext()); return(result); } } } throw Error.NoElements(); }
public static float Max <TSource>(this IEnumerable <TSource> source, Func <TSource, float> selector) { if (source == null) { throw Error.ArgumentNull("source"); } if (selector == null) { throw Error.ArgumentNull("selector"); } float value; using (IEnumerator <TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = selector(e.Current); while (float.IsNaN(value)) { if (!e.MoveNext()) { return(value); } value = selector(e.Current); } while (e.MoveNext()) { float x = selector(e.Current); if (x > value) { value = x; } } } return(value); }
public static float Min(this IEnumerable <float> source) { if (source == null) { throw Error.ArgumentNull("source"); } float value; using (IEnumerator <float> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = e.Current; while (e.MoveNext()) { float x = e.Current; if (x < value) { value = x; } // Normally NaN < anything is false, as is anything < NaN // However, this leads to some irksome outcomes in Min and Max. // If we use those semantics then Min(NaN, 5.0) is NaN, but // Min(5.0, NaN) is 5.0! To fix this, we impose a total // ordering where NaN is smaller than every value, including // negative infinity. // Not testing for NaN therefore isn't an option, but since we // can't find a smaller value, we can short-circuit. else if (float.IsNaN(x)) { return(x); } } } return(value); }
public static double Min <TSource>(this IEnumerable <TSource> source, Func <TSource, double> selector) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (selector == null) { throw Error.ArgumentNull(nameof(selector)); } double value; using (IEnumerator <TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = selector(e.Current); while (e.MoveNext()) { double x = selector(e.Current); if (x < value) { value = x; } else if (double.IsNaN(x)) { return(x); } } } return(value); }
public static double Max(this IEnumerable <double> source) { if (source == null) { throw Error.ArgumentNull("source"); } double value; using (IEnumerator <double> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = e.Current; // As described in a comment on Min(this IEnumerable<double>) NaN is ordered // less than all other values. We need to do explicit checks to ensure this, but // once we've found a value that is not NaN we need no longer worry about it, // so first loop until such a value is found (or not, as the case may be). while (double.IsNaN(value)) { if (!e.MoveNext()) { return(value); } value = e.Current; } while (e.MoveNext()) { double x = e.Current; if (x > value) { value = x; } } } return(value); }
public TElement Last() { CachingComparer <TElement> comparer = GetComparer(); using (IEnumerator <TElement> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } TElement value = e.Current; comparer.SetElement(value); while (e.MoveNext()) { TElement x = e.Current; if (comparer.Compare(x, false) >= 0) { value = x; } } return(value); } }
public static TSource Single <TSource>(this IEnumerable <TSource> source) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } IList <TSource> list = source as IList <TSource>; if (list != null) { switch (list.Count) { case 0: throw Error.NoElements(); case 1: return(list[0]); } } else { using (IEnumerator <TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } TSource result = e.Current; if (!e.MoveNext()) { return(result); } } } throw Error.MoreThanOneElement(); }
public static TSource Aggregate <TSource>(this IEnumerable <TSource> source, Func <TSource, TSource, TSource> func) { if (source == null) { throw Error.ArgumentNull("source"); } if (func == null) { throw Error.ArgumentNull("func"); } using (IEnumerator <TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } TSource result = e.Current; while (e.MoveNext()) { result = func(result, e.Current); } return(result); } }
static async ValueTask <TSource> Core(IAsyncEnumerable <TSource> source, CancellationToken cancellationToken) { var first = await TryGetFirst(source, cancellationToken).ConfigureAwait(false); return(first.HasValue ? first.Value : throw Error.NoElements()); }
public static TResult Max <TSource, TResult>(this IEnumerable <TSource> source, Func <TSource, TResult> selector) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (selector == null) { throw Error.ArgumentNull(nameof(selector)); } Comparer <TResult> comparer = Comparer <TResult> .Default; TResult value = default(TResult); if (value == null) { using (IEnumerator <TSource> e = source.GetEnumerator()) { do { if (!e.MoveNext()) { return(value); } value = selector(e.Current); }while (value == null); while (e.MoveNext()) { TResult x = selector(e.Current); if (x != null && comparer.Compare(x, value) > 0) { value = x; } } } } else { using (IEnumerator <TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) { throw Error.NoElements(); } value = selector(e.Current); while (e.MoveNext()) { TResult x = selector(e.Current); if (comparer.Compare(x, value) > 0) { value = x; } } } } return(value); }
public TElement Last() { throw Error.NoElements(); }
public TElement First() { throw Error.NoElements(); }
static async ValueTask <TSource> Core(IAsyncEnumerable <TSource> _source, CancellationToken _cancellationToken) { var last = await TryGetLast(_source, _cancellationToken).ConfigureAwait(false); return(last.HasValue ? last.Value : throw Error.NoElements()); }