You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
3.1 KiB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace IPA.Utilities
  8. {
  9. /// <summary>
  10. /// Extensions for <see cref="IEnumerable{T}"/> that don't currently exist in <c>System.Linq</c>.
  11. /// </summary>
  12. public static class EnumerableExtensions
  13. {
  14. /// <summary>
  15. /// Adds a value to the beginning of the sequence.
  16. /// </summary>
  17. /// <typeparam name="T">the type of the elements of <paramref name="seq"/></typeparam>
  18. /// <param name="seq">a sequence of values</param>
  19. /// <param name="prep">the value to prepend to <paramref name="seq"/></param>
  20. /// <returns>a new sequence beginning with <paramref name="prep"/></returns>
  21. public static IEnumerable<T> Prepend<T>(this IEnumerable<T> seq, T prep)
  22. => new PrependEnumerable<T>(seq, prep);
  23. private sealed class PrependEnumerable<T> : IEnumerable<T>
  24. {
  25. private readonly IEnumerable<T> rest;
  26. private readonly T first;
  27. public PrependEnumerable(IEnumerable<T> rest, T first)
  28. {
  29. this.rest = rest;
  30. this.first = first;
  31. }
  32. public IEnumerator<T> GetEnumerator()
  33. {
  34. yield return first;
  35. foreach (var v in rest) yield return v;
  36. }
  37. IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
  38. }
  39. /// <summary>
  40. /// LINQ extension method that filters <see langword="null"/> elements out of an enumeration.
  41. /// </summary>
  42. /// <typeparam name="T">the type of the enumeration</typeparam>
  43. /// <param name="self">the enumeration to filter</param>
  44. /// <returns>a filtered enumerable</returns>
  45. public static IEnumerable<T> NonNull<T>(this IEnumerable<T> self) where T : class
  46. => self.Where(o => o != null);
  47. /// <summary>
  48. /// LINQ extension method that filters <see langword="null"/> elements out of an enumeration based on a converter.
  49. /// </summary>
  50. /// <typeparam name="T">the type of the enumeration</typeparam>
  51. /// <typeparam name="U">the type to compare to null</typeparam>
  52. /// <param name="self">the enumeration to filter</param>
  53. /// <param name="pred">the predicate to select for filtering</param>
  54. /// <returns>a filtered enumerable</returns>
  55. public static IEnumerable<T> NonNull<T, U>(this IEnumerable<T> self, Func<T, U> pred) where T : class where U : class
  56. => self.Where(o => pred(o) != null);
  57. /// <summary>
  58. /// LINQ extension method that filters <see langword="null"/> elements from an enumeration of nullable types.
  59. /// </summary>
  60. /// <typeparam name="T">the underlying type of the nullable enumeration</typeparam>
  61. /// <param name="self">the enumeration to filter</param>
  62. /// <returns>a filtered enumerable</returns>
  63. public static IEnumerable<T> NonNull<T>(this IEnumerable<T?> self) where T : struct
  64. => self.Where(o => o != null).Select(o => o.Value);
  65. }
  66. }