浏览代码

More efficient Min and Max.

Bart De Smet 8 年之前
父节点
当前提交
5d1be7f7a5

+ 29 - 0
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs

@@ -86,5 +86,34 @@ namespace System.Linq
 
             return source.Select(selector).Max(cancellationToken);
         }
+
+        private static async Task<TSource> Max_<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
+        {
+            var e = source.GetAsyncEnumerator();
+
+            try
+            {
+                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+
+                var max = e.Current;
+
+                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                {
+                    var cur = e.Current;
+
+                    if (comparer.Compare(cur, max) > 0)
+                    {
+                        max = cur;
+                    }
+                }
+
+                return max;
+            }
+            finally
+            {
+                await e.DisposeAsync().ConfigureAwait(false);
+            }
+        }
     }
 }

+ 0 - 5
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MaxBy.cs

@@ -97,10 +97,5 @@ namespace System.Linq
 
             return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken);
         }
-
-        private static async Task<TSource> Max_<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
-        {
-            return (await MaxBy(source, x => x, comparer, cancellationToken).ConfigureAwait(false)).First();
-        }
     }
 }

+ 29 - 0
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs

@@ -86,5 +86,34 @@ namespace System.Linq
 
             return source.Select(selector).Min(cancellationToken);
         }
+
+        private static async Task<TSource> Min_<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
+        {
+            var e = source.GetAsyncEnumerator();
+
+            try
+            {
+                if (!await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                    throw new InvalidOperationException(Strings.NO_ELEMENTS);
+
+                var min = e.Current;
+
+                while (await e.MoveNextAsync(cancellationToken).ConfigureAwait(false))
+                {
+                    var cur = e.Current;
+
+                    if (comparer.Compare(cur, min) < 0)
+                    {
+                        min = cur;
+                    }
+                }
+
+                return min;
+            }
+            finally
+            {
+                await e.DisposeAsync().ConfigureAwait(false);
+            }
+        }
     }
 }

+ 0 - 5
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/MinBy.cs

@@ -98,11 +98,6 @@ namespace System.Linq
             return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken);
         }
 
-        private static async Task<TSource> Min_<TSource>(IAsyncEnumerable<TSource> source, IComparer<TSource> comparer, CancellationToken cancellationToken)
-        {
-            return (await MinBy(source, x => x, comparer, cancellationToken).ConfigureAwait(false)).First();
-        }
-
         private static async Task<IList<TSource>> ExtremaBy<TSource, TKey>(IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TKey, int> compare, CancellationToken cancellationToken)
         {
             var result = new List<TSource>();