ExtendIEnumerable.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Abc.Zebus.Util.Annotations;
  5. namespace Abc.Zebus.Util.Extensions
  6. {
  7. internal static class ExtendIEnumerable
  8. {
  9. #if !NETFWK
  10. [Pure]
  11. public static HashSet<T> ToHashSet<T>([InstantHandle] this IEnumerable<T> collection)
  12. {
  13. return new HashSet<T>(collection);
  14. }
  15. [Pure]
  16. public static HashSet<T> ToHashSet<T>([InstantHandle] this IEnumerable<T> collection, IEqualityComparer<T> comparer)
  17. {
  18. return new HashSet<T>(collection, comparer);
  19. }
  20. #endif
  21. [Pure]
  22. public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
  23. {
  24. var random = new Random();
  25. var buffer = source.ToList();
  26. for (var i = 0; i < buffer.Count; i++)
  27. {
  28. var randomIndex = random.Next(i, buffer.Count);
  29. yield return buffer[randomIndex];
  30. buffer[randomIndex] = buffer[i];
  31. }
  32. }
  33. [Pure]
  34. public static IList<T> AsList<T>([InstantHandle] this IEnumerable<T> collection)
  35. => collection is IList<T> list ? list : collection.ToList();
  36. [Pure]
  37. public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  38. {
  39. var seenKeys = new HashSet<TKey>();
  40. return source.Where(element => seenKeys.Add(keySelector(element)));
  41. }
  42. /// <summary>
  43. /// Performs the specified <see cref="Action{T}" /> against every element of <see cref="IEnumerable{T}" />
  44. /// </summary>
  45. /// <typeparam name="T"></typeparam>
  46. /// <param name="enumerable">Enumerable to extend</param>
  47. /// <param name="action">Action to perform</param>
  48. /// <exception cref="ArgumentNullException">When any parameter is null</exception>
  49. public static void ForEach<T>([InstantHandle] this IEnumerable<T> enumerable, [InstantHandle] Action<T> action)
  50. {
  51. if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
  52. if (action == null) throw new ArgumentNullException(nameof(action));
  53. foreach (var t in enumerable)
  54. {
  55. action(t);
  56. }
  57. }
  58. /// <summary>
  59. /// Hides the underlying implementation
  60. /// </summary>
  61. public static IEnumerable<T> AsReadOnlyEnumerable<T>(this IEnumerable<T> items)
  62. {
  63. foreach (var item in items)
  64. yield return item;
  65. }
  66. }
  67. }