mirror of
https://github.com/ICDSystems/ICD.Common.Utils.git
synced 2026-02-15 20:54:58 +00:00
refactor: Separating iterators from validation
This commit is contained in:
@@ -42,10 +42,8 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (predicate == null)
|
if (predicate == null)
|
||||||
throw new ArgumentNullException("predicate");
|
throw new ArgumentNullException("predicate");
|
||||||
|
|
||||||
foreach (T item in extends.Where(predicate))
|
T output;
|
||||||
return item;
|
return extends.TryFirst(predicate, out output) ? output : defaultItem;
|
||||||
|
|
||||||
return defaultItem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -309,9 +307,21 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (match == null)
|
if (match == null)
|
||||||
throw new ArgumentNullException("match");
|
throw new ArgumentNullException("match");
|
||||||
|
|
||||||
|
return FindIndicesIterator(extends, match);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the indices that match the predicate.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="match"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<int> FindIndicesIterator<T>(IEnumerable<T> sequence, Predicate<T> match)
|
||||||
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
foreach (T item in extends)
|
foreach (T item in sequence)
|
||||||
{
|
{
|
||||||
if (match(item))
|
if (match(item))
|
||||||
yield return index;
|
yield return index;
|
||||||
@@ -405,8 +415,21 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (extends == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("extends");
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
|
return PrependIterator(extends, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepends the item to the start of the sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> PrependIterator<T>(IEnumerable<T> sequence, T item)
|
||||||
|
{
|
||||||
yield return item;
|
yield return item;
|
||||||
foreach (T next in extends)
|
|
||||||
|
foreach (T next in sequence)
|
||||||
yield return next;
|
yield return next;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -427,9 +450,22 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (items == null)
|
if (items == null)
|
||||||
throw new ArgumentNullException("items");
|
throw new ArgumentNullException("items");
|
||||||
|
|
||||||
|
return PrependManyIterator(extends, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepends the items to the start of the sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="items"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> PrependManyIterator<T>(IEnumerable<T> sequence, params T[] items)
|
||||||
|
{
|
||||||
foreach (T item in items)
|
foreach (T item in items)
|
||||||
yield return item;
|
yield return item;
|
||||||
foreach (T each in extends)
|
|
||||||
|
foreach (T each in sequence)
|
||||||
yield return each;
|
yield return each;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,8 +482,21 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (extends == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("extends");
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
foreach (T first in extends)
|
return AppendIterator(extends, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends the item to the end of the sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="item"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> AppendIterator<T>(IEnumerable<T> sequence, T item)
|
||||||
|
{
|
||||||
|
foreach (T first in sequence)
|
||||||
yield return first;
|
yield return first;
|
||||||
|
|
||||||
yield return item;
|
yield return item;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -468,8 +517,21 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (items == null)
|
if (items == null)
|
||||||
throw new ArgumentNullException("items");
|
throw new ArgumentNullException("items");
|
||||||
|
|
||||||
foreach (T each in extends)
|
return AppendManyIterator(extends, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends the items to the end of the sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="items"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> AppendManyIterator<T>(IEnumerable<T> sequence, params T[] items)
|
||||||
|
{
|
||||||
|
foreach (T each in sequence)
|
||||||
yield return each;
|
yield return each;
|
||||||
|
|
||||||
foreach (T item in items)
|
foreach (T item in items)
|
||||||
yield return item;
|
yield return item;
|
||||||
}
|
}
|
||||||
@@ -487,9 +549,21 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (extends == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("extends");
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
|
return PadRightIterator(extends, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pads the given sequence to the given count size with default items.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="count"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> PadRightIterator<T>(IEnumerable<T> sequence, int count)
|
||||||
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
foreach (T item in extends)
|
foreach (T item in sequence)
|
||||||
{
|
{
|
||||||
yield return item;
|
yield return item;
|
||||||
index++;
|
index++;
|
||||||
@@ -801,7 +875,18 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (extends == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("extends");
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
using (IEnumerator<T> enumerator = extends.GetEnumerator())
|
return PartitionIterator(extends, partitionSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Partitions a sequence into sequences of the given length.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="partitionSize"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<IEnumerable<T>> PartitionIterator<T>(IEnumerable<T> sequence, int partitionSize)
|
||||||
|
{
|
||||||
|
using (IEnumerator<T> enumerator = sequence.GetEnumerator())
|
||||||
{
|
{
|
||||||
while (enumerator.MoveNext())
|
while (enumerator.MoveNext())
|
||||||
yield return YieldBatchElements(enumerator, partitionSize - 1);
|
yield return YieldBatchElements(enumerator, partitionSize - 1);
|
||||||
@@ -826,9 +911,9 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wraps this object instance into an IEnumerable consisting of a single item.
|
/// Wraps this object instance into an IEnumerable consisting of a single item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"> Type of the object. </typeparam>
|
/// <typeparam name="T">Type of the object.</typeparam>
|
||||||
/// <param name="item"> The instance that will be wrapped. </param>
|
/// <param name="item">The instance that will be wrapped.</param>
|
||||||
/// <returns> An IEnumerable<T> consisting of a single item. </returns>
|
/// <returns>An IEnumerable<T> consisting of a single item.</returns>
|
||||||
public static IEnumerable<T> Yield<T>(this T item)
|
public static IEnumerable<T> Yield<T>(this T item)
|
||||||
{
|
{
|
||||||
yield return item;
|
yield return item;
|
||||||
@@ -841,6 +926,20 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
/// <param name="extends"></param>
|
/// <param name="extends"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IEnumerable<T[]> GetAdjacentPairs<T>(this IEnumerable<T> extends)
|
public static IEnumerable<T[]> GetAdjacentPairs<T>(this IEnumerable<T> extends)
|
||||||
|
{
|
||||||
|
if (extends == null)
|
||||||
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
|
return GetAdjacentPairsIterator(extends);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Given a sequence [A, B, C] returns a sequence [[A, B], [B, C]]
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="extends"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T[]> GetAdjacentPairsIterator<T>(IEnumerable<T> extends)
|
||||||
{
|
{
|
||||||
T previous = default(T);
|
T previous = default(T);
|
||||||
bool first = true;
|
bool first = true;
|
||||||
@@ -848,7 +947,7 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
foreach (T item in extends)
|
foreach (T item in extends)
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
yield return new[] {previous, item};
|
yield return new[] { previous, item };
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
previous = item;
|
previous = item;
|
||||||
@@ -932,18 +1031,22 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
{
|
{
|
||||||
if (!sourceIterator.MoveNext())
|
if (!sourceIterator.MoveNext())
|
||||||
throw new InvalidOperationException("Sequence contains no elements");
|
throw new InvalidOperationException("Sequence contains no elements");
|
||||||
|
|
||||||
TSource min = sourceIterator.Current;
|
TSource min = sourceIterator.Current;
|
||||||
TKey minKey = selector(min);
|
TKey minKey = selector(min);
|
||||||
|
|
||||||
while (sourceIterator.MoveNext())
|
while (sourceIterator.MoveNext())
|
||||||
{
|
{
|
||||||
TSource candidate = sourceIterator.Current;
|
TSource candidate = sourceIterator.Current;
|
||||||
TKey candidateProjected = selector(candidate);
|
TKey candidateProjected = selector(candidate);
|
||||||
|
|
||||||
if (comparer.Compare(candidateProjected, minKey) >= 0)
|
if (comparer.Compare(candidateProjected, minKey) >= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
min = candidate;
|
min = candidate;
|
||||||
minKey = candidateProjected;
|
minKey = candidateProjected;
|
||||||
}
|
}
|
||||||
|
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1017,16 +1120,33 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
if (comparer == null)
|
if (comparer == null)
|
||||||
throw new ArgumentNullException("comparer");
|
throw new ArgumentNullException("comparer");
|
||||||
|
|
||||||
|
return ConsolidateIterator(extends, comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Skips duplicate, consecutive items.
|
||||||
|
/// E.g.
|
||||||
|
/// [1, 2, 2, 3, 1, 1]
|
||||||
|
/// Becomes
|
||||||
|
/// [1, 2, 3, 1]
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="sequence"></param>
|
||||||
|
/// <param name="comparer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<T> ConsolidateIterator<T>(IEnumerable<T> sequence, IComparer<T> comparer)
|
||||||
|
{
|
||||||
bool first = true;
|
bool first = true;
|
||||||
T last = default(T);
|
T last = default(T);
|
||||||
|
|
||||||
foreach (T item in extends)
|
foreach (T item in sequence)
|
||||||
{
|
{
|
||||||
if (!first && comparer.Compare(last, item) == 0)
|
if (!first && comparer.Compare(last, item) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
last = item;
|
last = item;
|
||||||
|
|
||||||
yield return item;
|
yield return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1141,23 +1261,40 @@ namespace ICD.Common.Utils.Extensions
|
|||||||
/// <typeparam name="TFirst"></typeparam>
|
/// <typeparam name="TFirst"></typeparam>
|
||||||
/// <typeparam name="TSecond"></typeparam>
|
/// <typeparam name="TSecond"></typeparam>
|
||||||
/// <typeparam name="TResult"></typeparam>
|
/// <typeparam name="TResult"></typeparam>
|
||||||
/// <param name="first"></param>
|
/// <param name="extends"></param>
|
||||||
/// <param name="second"></param>
|
/// <param name="other"></param>
|
||||||
/// <param name="callback"></param>
|
/// <param name="callback"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first,
|
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> extends,
|
||||||
IEnumerable<TSecond> second,
|
IEnumerable<TSecond> other,
|
||||||
Func<TFirst, TSecond, TResult> callback)
|
Func<TFirst, TSecond, TResult> callback)
|
||||||
{
|
{
|
||||||
if (first == null)
|
if (extends == null)
|
||||||
throw new ArgumentNullException("first");
|
throw new ArgumentNullException("extends");
|
||||||
|
|
||||||
if (second == null)
|
if (other == null)
|
||||||
throw new ArgumentNullException("second");
|
throw new ArgumentNullException("other");
|
||||||
|
|
||||||
if (callback == null)
|
if (callback == null)
|
||||||
throw new ArgumentNullException("callback");
|
throw new ArgumentNullException("callback");
|
||||||
|
|
||||||
|
return ZipIterator(extends, other, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies a specified function to the corresponding elements of two sequences, producing a sequence of the results.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TFirst"></typeparam>
|
||||||
|
/// <typeparam name="TSecond"></typeparam>
|
||||||
|
/// <typeparam name="TResult"></typeparam>
|
||||||
|
/// <param name="first"></param>
|
||||||
|
/// <param name="second"></param>
|
||||||
|
/// <param name="callback"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>(IEnumerable<TFirst> first,
|
||||||
|
IEnumerable<TSecond> second,
|
||||||
|
Func<TFirst, TSecond, TResult> callback)
|
||||||
|
{
|
||||||
using (IEnumerator<TFirst> enumerator1 = first.GetEnumerator())
|
using (IEnumerator<TFirst> enumerator1 = first.GetEnumerator())
|
||||||
{
|
{
|
||||||
using (IEnumerator<TSecond> enumerator2 = second.GetEnumerator())
|
using (IEnumerator<TSecond> enumerator2 = second.GetEnumerator())
|
||||||
|
|||||||
Reference in New Issue
Block a user