Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- namespace PersonalUtilities;
- /// <summary>
- /// Provides extension methods to enumerate a <see cref="Range"/> using foreach and LINQ.
- /// </summary>
- public static class RangeEnumerable
- {
- /// <summary>
- /// Enumerates a <see cref="Range"/>.
- /// </summary>
- public struct Enumerator : IEnumerator<int>, IEnumerable<int>
- {
- private int current;
- private int state;
- private readonly int start;
- private readonly int end;
- private readonly int direction;
- public int Current => current;
- public bool MoveNext()
- {
- switch (state)
- {
- case 0:
- if (direction == 1)
- state = 1;
- else if(direction == -1)
- state = 2;
- return true;
- case 1:
- current++;
- if (current >= end)
- state = 4;
- return true;
- case 2:
- current--;
- if (current <= end)
- state = 4;
- return true;
- case 3:
- state = 4;
- return true;
- case 4:
- return false;
- default:
- return false;
- }
- }
- public void Dispose() { }
- internal Enumerator(Range range) : this(range.Start, range.End) { }
- internal Enumerator(Index start, Index end) : this(start.GetOffset(0), end.GetOffset(0)) { }
- internal Enumerator(int start, int end)
- {
- this.direction = Math.Sign(end - start);
- this.state = direction == 0 ? 3 : 0;
- this.current = start;
- this.start = start;
- this.end = end;
- }
- object IEnumerator.Current => current;
- void IEnumerator.Reset()
- {
- current = start;
- state = direction == 0 ? 3 : 0;
- }
- IEnumerator<int> IEnumerable<int>.GetEnumerator() => this;
- IEnumerator IEnumerable.GetEnumerator() => this;
- }
- /// <summary>
- /// Allows <see cref="Range"/> to be enumerated with foreach.
- /// </summary>
- /// <param name="range">The <see cref="Range"/> to enumerate.</param>
- /// <returns>
- /// Returns an enumerator that iterates through the integers of a <see cref="Range"/>.
- /// </returns>
- /// <seealso cref="AsEnumerable(Range)"/>
- public static Enumerator GetEnumerator(this Range range)
- => new(range);
- /// <summary>
- /// Allows <see cref="Range"/> to be used with LINQ Extension methods.
- /// </summary>
- /// <param name="range">The <see cref="Range"/> to enumerate.</param>
- /// <returns>
- /// An <see cref="IEnumerable{int}"/> whose elements are each integer of a <see cref="Range"/>.
- /// </returns>
- /// <seealso cref="GetEnumerator(Range)"/>
- public static IEnumerable<int> AsEnumerable(this Range range)
- => new Enumerator(range);
- /// <summary>
- /// Projects each integer of a range into a new form.
- /// </summary>
- /// <inheritdoc cref="Enumerable.Select{TSource, TResult}(IEnumerable{TSource}, Func{TSource, TResult})"/>
- /// <typeparam name="TResult"></typeparam>
- /// <param name="range"></param>
- /// <param name="selector"></param>
- public static IEnumerable<TResult> Select<TResult>(this Range range, Func<int, TResult> selector)
- => Enumerable.Select(range.AsEnumerable(), selector);
- /// <summary>
- /// Projects each integer of a range into a new form by incorporating the element's index.
- /// </summary>
- /// <inheritdoc cref="Enumerable.Select{TSource, TResult}(IEnumerable{TSource}, Func{TSource, int, TResult})"/>
- /// <typeparam name="TResult"></typeparam>
- /// <param name="range"></param>
- /// <param name="selector"></param>
- public static IEnumerable<TResult> Select<TResult>(this Range range, Func<int, int, TResult> selector)
- => Enumerable.Select(range.AsEnumerable(), selector);
- /// <summary>
- /// Creates an array of integers from a <see cref="Range"/>.
- /// </summary>
- /// <param name="range">
- /// A <see cref="Range"/> from which the array is created.
- /// </param>
- /// <returns></returns>
- public static int[] ToArray(this Range range)
- => range.AsEnumerable().ToArray();
- /// <summary>
- /// Creates a <see cref="List{T}"/> of integers from a <see cref="Range"/>.
- /// </summary>
- /// <param name="range">
- /// A <see cref="Range"/> from which the <see cref="List{T}"/> is created.
- /// </param>
- /// <returns>A <see cref="List{T}"/> of <see cref="int"/>.</returns>
- public static List<int> ToList(this Range range)
- => range.AsEnumerable().ToList();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement