OrderBy.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. namespace System.Linq
  8. {
  9. public static partial class AsyncEnumerable
  10. {
  11. /// <summary>
  12. /// Sorts the elements of a sequence in ascending order according to a key.
  13. /// </summary>
  14. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  15. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  16. /// <param name="source">An async-enumerable sequence of values to order.</param>
  17. /// <param name="keySelector">A function to extract a key from an element.</param>
  18. /// <returns>An ordered async-enumerable sequence whose elements are sorted according to a key.</returns>
  19. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  20. public static IOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) =>
  21. new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer: null, descending: false, parent: null);
  22. internal static IOrderedAsyncEnumerable<TSource> OrderByAwaitCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector) =>
  23. new OrderedAsyncEnumerableWithTask<TSource, TKey>(source, keySelector, comparer: null, descending: false, parent: null);
  24. #if !NO_DEEP_CANCELLATION
  25. internal static IOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellationCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector) =>
  26. new OrderedAsyncEnumerableWithTaskAndCancellation<TSource, TKey>(source, keySelector, comparer: null, descending: false, parent: null);
  27. #endif
  28. /// <summary>
  29. /// Sorts the elements of a sequence in ascending order by using a specified comparer.
  30. /// </summary>
  31. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  32. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  33. /// <param name="source">An async-enumerable sequence of values to order.</param>
  34. /// <param name="keySelector">A function to extract a key from an element.</param>
  35. /// <param name="comparer">A comparer to compare keys.</param>
  36. /// <returns>An ordered async-enumerable sequence whose elements are sorted according to a key.</returns>
  37. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  38. public static IOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) =>
  39. new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, descending: false, parent: null);
  40. internal static IOrderedAsyncEnumerable<TSource> OrderByAwaitCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey> comparer) =>
  41. new OrderedAsyncEnumerableWithTask<TSource, TKey>(source, keySelector, comparer, descending: false, parent: null);
  42. #if !NO_DEEP_CANCELLATION
  43. internal static IOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellationCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey> comparer) =>
  44. new OrderedAsyncEnumerableWithTaskAndCancellation<TSource, TKey>(source, keySelector, comparer, descending: false, parent: null);
  45. #endif
  46. /// <summary>
  47. /// Sorts the elements of a sequence in descending order according to a key.
  48. /// </summary>
  49. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  50. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  51. /// <param name="source">An async-enumerable sequence of values to order.</param>
  52. /// <param name="keySelector">A function to extract a key from an element.</param>
  53. /// <returns>An ordered async-enumerable sequence whose elements are sorted in descending order according to a key.</returns>
  54. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  55. public static IOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) =>
  56. new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer: null, descending: true, parent: null);
  57. internal static IOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector) =>
  58. new OrderedAsyncEnumerableWithTask<TSource, TKey>(source, keySelector, comparer: null, descending: true, parent: null);
  59. #if !NO_DEEP_CANCELLATION
  60. internal static IOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellationCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector) =>
  61. new OrderedAsyncEnumerableWithTaskAndCancellation<TSource, TKey>(source, keySelector, comparer: null, descending: true, parent: null);
  62. #endif
  63. /// <summary>
  64. /// Sorts the elements of a sequence in descending order by using a specified comparer.
  65. /// </summary>
  66. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  67. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  68. /// <param name="source">An async-enumerable sequence of values to order.</param>
  69. /// <param name="keySelector">A function to extract a key from an element.</param>
  70. /// <param name="comparer">A comparer to compare keys.</param>
  71. /// <returns>An ordered async-enumerable sequence whose elements are sorted in descending order according to a key.</returns>
  72. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  73. public static IOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) =>
  74. new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, descending: true, parent: null);
  75. internal static IOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey> comparer) =>
  76. new OrderedAsyncEnumerableWithTask<TSource, TKey>(source, keySelector, comparer, descending: true, parent: null);
  77. #if !NO_DEEP_CANCELLATION
  78. internal static IOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellationCore<TSource, TKey>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey> comparer) =>
  79. new OrderedAsyncEnumerableWithTaskAndCancellation<TSource, TKey>(source, keySelector, comparer, descending: true, parent: null);
  80. #endif
  81. /// <summary>
  82. /// Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
  83. /// </summary>
  84. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  85. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  86. /// <param name="source">An ordered async-enumerable sequence that contains elements to sort.</param>
  87. /// <param name="keySelector">A function to extract a key from each element.</param>
  88. /// <returns>An ordered async-enumerable whose elements are sorted according to a key.</returns>
  89. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  90. public static IOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  91. {
  92. if (source == null)
  93. throw Error.ArgumentNull(nameof(source));
  94. return source.CreateOrderedEnumerable(keySelector, comparer: null, descending: false);
  95. }
  96. internal static IOrderedAsyncEnumerable<TSource> ThenByAwaitCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector)
  97. {
  98. if (source == null)
  99. throw Error.ArgumentNull(nameof(source));
  100. return source.CreateOrderedEnumerable(keySelector, comparer: default(IComparer<TKey>), descending: false);
  101. }
  102. #if !NO_DEEP_CANCELLATION
  103. internal static IOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellationCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector)
  104. {
  105. if (source == null)
  106. throw Error.ArgumentNull(nameof(source));
  107. return source.CreateOrderedEnumerable(keySelector, comparer: null, descending: false);
  108. }
  109. #endif
  110. /// <summary>
  111. /// Performs a subsequent ordering of the elements in a sequence in ascending order by using a specified comparer.
  112. /// </summary>
  113. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  114. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  115. /// <param name="source">An ordered async-enumerable sequence that contains elements to sort.</param>
  116. /// <param name="keySelector">A function to extract a key from each element.</param>
  117. /// <param name="comparer">A comparer to compare keys.</param>
  118. /// <returns>An ordered async-enumerable whose elements are sorted according to a key.</returns>
  119. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  120. public static IOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  121. {
  122. if (source == null)
  123. throw Error.ArgumentNull(nameof(source));
  124. return source.CreateOrderedEnumerable(keySelector, comparer, descending: false);
  125. }
  126. internal static IOrderedAsyncEnumerable<TSource> ThenByAwaitCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey> comparer)
  127. {
  128. if (source == null)
  129. throw Error.ArgumentNull(nameof(source));
  130. return source.CreateOrderedEnumerable(keySelector, comparer, descending: false);
  131. }
  132. #if !NO_DEEP_CANCELLATION
  133. internal static IOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellationCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey> comparer)
  134. {
  135. if (source == null)
  136. throw Error.ArgumentNull(nameof(source));
  137. return source.CreateOrderedEnumerable(keySelector, comparer, descending: false);
  138. }
  139. #endif
  140. /// <summary>
  141. /// Performs a subsequent ordering of the elements in a sequence in descending order, according to a key.
  142. /// </summary>
  143. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  144. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  145. /// <param name="source">An ordered async-enumerable sequence that contains elements to sort.</param>
  146. /// <param name="keySelector">A function to extract a key from each element.</param>
  147. /// <returns>An ordered async-enumerable sequence whose elements are sorted in descending order according to a key.</returns>
  148. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  149. public static IOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  150. {
  151. if (source == null)
  152. throw Error.ArgumentNull(nameof(source));
  153. return source.CreateOrderedEnumerable(keySelector, comparer: null, descending: true);
  154. }
  155. internal static IOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector)
  156. {
  157. if (source == null)
  158. throw Error.ArgumentNull(nameof(source));
  159. return source.CreateOrderedEnumerable(keySelector, comparer: default(IComparer<TKey>), descending: true);
  160. }
  161. #if !NO_DEEP_CANCELLATION
  162. internal static IOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellationCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector)
  163. {
  164. if (source == null)
  165. throw Error.ArgumentNull(nameof(source));
  166. return source.CreateOrderedEnumerable(keySelector, comparer: null, descending: true);
  167. }
  168. #endif
  169. /// <summary>
  170. /// Performs a subsequent ordering of the elements in a sequence in descending order by using a specified comparer.
  171. /// </summary>
  172. /// <typeparam name="TSource">The type of the elements of source.</typeparam>
  173. /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
  174. /// <param name="source">An ordered async-enumerable sequence that contains elements to sort.</param>
  175. /// <param name="keySelector">A function to extract a key from each element.</param>
  176. /// <param name="comparer">A comparer to compare keys.</param>
  177. /// <returns>An ordered async-enumerable sequence whose elements are sorted in descending order according to a key.</returns>
  178. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="keySelector"/> is null.</exception>
  179. public static IOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  180. {
  181. if (source == null)
  182. throw Error.ArgumentNull(nameof(source));
  183. return source.CreateOrderedEnumerable(keySelector, comparer, descending: true);
  184. }
  185. internal static IOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TKey>> keySelector, IComparer<TKey> comparer)
  186. {
  187. if (source == null)
  188. throw Error.ArgumentNull(nameof(source));
  189. return source.CreateOrderedEnumerable(keySelector, comparer, descending: true);
  190. }
  191. #if !NO_DEEP_CANCELLATION
  192. internal static IOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellationCore<TSource, TKey>(this IOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TKey>> keySelector, IComparer<TKey> comparer)
  193. {
  194. if (source == null)
  195. throw Error.ArgumentNull(nameof(source));
  196. return source.CreateOrderedEnumerable(keySelector, comparer, descending: true);
  197. }
  198. #endif
  199. }
  200. }