|
|
@@ -40,6 +40,66 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static async Task<double> AverageCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ long sum = selector(e.Current);
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += selector(e.Current);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ long sum = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += await selector(e.Current).ConfigureAwait(false);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static async Task<double?> AverageCore(IAsyncEnumerable<int?> source, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
@@ -51,7 +111,415 @@ namespace System.Linq
|
|
|
var v = e.Current;
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
- long sum = v.GetValueOrDefault();
|
|
|
+ long sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = e.Current;
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, int?> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ long sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int?>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ long sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore(IAsyncEnumerable<long> source, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = e.Current;
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += e.Current;
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, long> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = selector(e.Current);
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += selector(e.Current);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += await selector(e.Current).ConfigureAwait(false);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore(IAsyncEnumerable<long?> source, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = e.Current;
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = e.Current;
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, long?> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long?>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (double)sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore(IAsyncEnumerable<double> source, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = e.Current;
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ // There is an opportunity to short-circuit here, in that if e.Current is
|
|
|
+ // ever NaN then the result will always be NaN. Assuming that this case is
|
|
|
+ // rare enough that not checking is the better approach generally.
|
|
|
+ sum += e.Current;
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, double> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = selector(e.Current);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ // There is an opportunity to short-circuit here, in that if e.Current is
|
|
|
+ // ever NaN then the result will always be NaN. Assuming that this case is
|
|
|
+ // rare enough that not checking is the better approach generally.
|
|
|
+ sum += selector(e.Current);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ // There is an opportunity to short-circuit here, in that if e.Current is
|
|
|
+ // ever NaN then the result will always be NaN. Assuming that this case is
|
|
|
+ // rare enough that not checking is the better approach generally.
|
|
|
+ sum += await selector(e.Current).ConfigureAwait(false);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<double?> AverageCore(IAsyncEnumerable<double?> source, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = e.Current;
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
long count = 1;
|
|
|
checked
|
|
|
{
|
|
|
@@ -66,7 +534,7 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return (double)sum / count;
|
|
|
+ return sum / count;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -78,37 +546,45 @@ namespace System.Linq
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private static async Task<double> AverageCore(IAsyncEnumerable<long> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, double?> selector, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
- {
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
-
|
|
|
- var sum = e.Current;
|
|
|
- long count = 1;
|
|
|
- checked
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ var v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
{
|
|
|
- sum += e.Current;
|
|
|
- ++count;
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return (double)sum / count;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
await e.DisposeAsync().ConfigureAwait(false);
|
|
|
}
|
|
|
+
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- private static async Task<double?> AverageCore(IAsyncEnumerable<long?> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<double?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double?>> selector, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
@@ -116,7 +592,7 @@ namespace System.Linq
|
|
|
{
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- var v = e.Current;
|
|
|
+ var v = await selector(e.Current).ConfigureAwait(false);
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
var sum = v.GetValueOrDefault();
|
|
|
@@ -125,7 +601,7 @@ namespace System.Linq
|
|
|
{
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- v = e.Current;
|
|
|
+ v = await selector(e.Current).ConfigureAwait(false);
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
sum += v.GetValueOrDefault();
|
|
|
@@ -134,7 +610,7 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return (double)sum / count;
|
|
|
+ return sum / count;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -146,7 +622,7 @@ namespace System.Linq
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private static async Task<double> AverageCore(IAsyncEnumerable<double> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<float> AverageCore(IAsyncEnumerable<float> source, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
@@ -157,18 +633,15 @@ namespace System.Linq
|
|
|
throw Error.NoElements();
|
|
|
}
|
|
|
|
|
|
- var sum = e.Current;
|
|
|
+ double sum = e.Current;
|
|
|
long count = 1;
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- // There is an opportunity to short-circuit here, in that if e.Current is
|
|
|
- // ever NaN then the result will always be NaN. Assuming that this case is
|
|
|
- // rare enough that not checking is the better approach generally.
|
|
|
sum += e.Current;
|
|
|
++count;
|
|
|
}
|
|
|
|
|
|
- return sum / count;
|
|
|
+ return (float)(sum / count);
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
@@ -176,7 +649,61 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static async Task<double?> AverageCore(IAsyncEnumerable<double?> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<float> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, float> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ double sum = selector(e.Current);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += selector(e.Current);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (float)(sum / count);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<float> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ double sum = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += await selector(e.Current).ConfigureAwait(false);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (float)(sum / count);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<float?> AverageCore(IAsyncEnumerable<float?> source, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
@@ -187,7 +714,7 @@ namespace System.Linq
|
|
|
var v = e.Current;
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
- var sum = v.GetValueOrDefault();
|
|
|
+ double sum = v.GetValueOrDefault();
|
|
|
long count = 1;
|
|
|
checked
|
|
|
{
|
|
|
@@ -202,7 +729,7 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return sum / count;
|
|
|
+ return (float)(sum / count);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -214,34 +741,45 @@ namespace System.Linq
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- private static async Task<float> AverageCore(IAsyncEnumerable<float> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<float?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, float?> selector, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
- {
|
|
|
- throw Error.NoElements();
|
|
|
- }
|
|
|
-
|
|
|
- double sum = e.Current;
|
|
|
- long count = 1;
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- sum += e.Current;
|
|
|
- ++count;
|
|
|
- }
|
|
|
+ var v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ double sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ checked
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return (float)(sum / count);
|
|
|
+ return (float)(sum / count);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
await e.DisposeAsync().ConfigureAwait(false);
|
|
|
}
|
|
|
+
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- private static async Task<float?> AverageCore(IAsyncEnumerable<float?> source, CancellationToken cancellationToken)
|
|
|
+ private static async Task<float?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float?>> selector, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
|
|
|
@@ -249,7 +787,7 @@ namespace System.Linq
|
|
|
{
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- var v = e.Current;
|
|
|
+ var v = await selector(e.Current).ConfigureAwait(false);
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
double sum = v.GetValueOrDefault();
|
|
|
@@ -258,7 +796,7 @@ namespace System.Linq
|
|
|
{
|
|
|
while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
{
|
|
|
- v = e.Current;
|
|
|
+ v = await selector(e.Current).ConfigureAwait(false);
|
|
|
if (v.HasValue)
|
|
|
{
|
|
|
sum += v.GetValueOrDefault();
|
|
|
@@ -306,6 +844,60 @@ namespace System.Linq
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static async Task<decimal> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, decimal> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = selector(e.Current);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += selector(e.Current);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<decimal> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ throw Error.NoElements();
|
|
|
+ }
|
|
|
+
|
|
|
+ var sum = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ sum += await selector(e.Current).ConfigureAwait(false);
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static async Task<decimal?> AverageCore(IAsyncEnumerable<decimal?> source, CancellationToken cancellationToken)
|
|
|
{
|
|
|
var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
@@ -340,5 +932,75 @@ namespace System.Linq
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
+ private static async Task<decimal?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, decimal?> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = selector(e.Current);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static async Task<decimal?> AverageCore<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal?>> selector, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ var e = source.GetAsyncEnumerator(cancellationToken);
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ var v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ var sum = v.GetValueOrDefault();
|
|
|
+ long count = 1;
|
|
|
+ while (await e.MoveNextAsync().ConfigureAwait(false))
|
|
|
+ {
|
|
|
+ v = await selector(e.Current).ConfigureAwait(false);
|
|
|
+ if (v.HasValue)
|
|
|
+ {
|
|
|
+ sum += v.GetValueOrDefault();
|
|
|
+ ++count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sum / count;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await e.DisposeAsync().ConfigureAwait(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
}
|