235 lines
5.5 KiB
C#
235 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace uNature.Wrappers.Linq
|
|
{
|
|
public static class LinqWrapper
|
|
{
|
|
private enum Fallback
|
|
{
|
|
Default = 0,
|
|
Throw = 1
|
|
}
|
|
|
|
public static bool Contains<T>(this T[] arr, T obj)
|
|
{
|
|
for (int i = 0; i < arr.Length; i++)
|
|
{
|
|
if (arr[i].Equals(obj))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static List<T> ToList<T>(this T[] arr)
|
|
{
|
|
List<T> list = new List<T>(arr.Length);
|
|
for (int i = 0; i < arr.Length; i++)
|
|
{
|
|
list.Add(arr[i]);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
|
|
{
|
|
Check.SourceAndSelector(source, selector);
|
|
return CreateSelectIterator(source, selector);
|
|
}
|
|
|
|
private static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
|
|
{
|
|
foreach (TSource element in source)
|
|
{
|
|
yield return selector(element);
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
|
|
{
|
|
Check.SourceAndSelector(source, selector);
|
|
return CreateSelectIterator(source, selector);
|
|
}
|
|
|
|
private static IEnumerable<TResult> CreateSelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
|
|
{
|
|
int counter = 0;
|
|
foreach (TSource element in source)
|
|
{
|
|
yield return selector(element, counter);
|
|
counter++;
|
|
}
|
|
}
|
|
|
|
public static int Count<TSource>(this IEnumerable<TSource> source)
|
|
{
|
|
Check.Source(source);
|
|
ICollection<TSource> collection = source as ICollection<TSource>;
|
|
if (collection != null)
|
|
{
|
|
return collection.Count;
|
|
}
|
|
int num = 0;
|
|
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
|
|
{
|
|
while (enumerator.MoveNext())
|
|
{
|
|
num = checked(num + 1);
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
|
|
public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
|
{
|
|
Check.SourceAndSelector(source, predicate);
|
|
int num = 0;
|
|
foreach (TSource item in source)
|
|
{
|
|
if (predicate(item))
|
|
{
|
|
num = checked(num + 1);
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
private static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, Fallback fallback)
|
|
{
|
|
foreach (TSource item in source)
|
|
{
|
|
if (predicate(item))
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
if (fallback == Fallback.Throw)
|
|
{
|
|
throw NoMatchingElement();
|
|
}
|
|
return default(TSource);
|
|
}
|
|
|
|
public static TSource First<TSource>(this IEnumerable<TSource> source)
|
|
{
|
|
Check.Source(source);
|
|
IList<TSource> list = source as IList<TSource>;
|
|
if (list != null)
|
|
{
|
|
if (list.Count != 0)
|
|
{
|
|
return list[0];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
|
|
{
|
|
if (enumerator.MoveNext())
|
|
{
|
|
return enumerator.Current;
|
|
}
|
|
}
|
|
}
|
|
throw EmptySequence();
|
|
}
|
|
|
|
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
|
{
|
|
Check.SourceAndPredicate(source, predicate);
|
|
return source.First(predicate, Fallback.Throw);
|
|
}
|
|
|
|
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
|
|
{
|
|
Check.Source(source);
|
|
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
|
|
{
|
|
if (enumerator.MoveNext())
|
|
{
|
|
return enumerator.Current;
|
|
}
|
|
}
|
|
return default(TSource);
|
|
}
|
|
|
|
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
|
{
|
|
Check.SourceAndPredicate(source, predicate);
|
|
return source.First(predicate, Fallback.Default);
|
|
}
|
|
|
|
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
|
{
|
|
return source.OrderBy(keySelector, null);
|
|
}
|
|
|
|
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
|
|
{
|
|
Check.SourceAndKeySelector(source, keySelector);
|
|
return new OrderedSequence<TSource, TKey>(source, keySelector, comparer, SortDirection.Ascending);
|
|
}
|
|
|
|
public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
|
|
{
|
|
Check.Source(source);
|
|
ICollection<TSource> collection = source as ICollection<TSource>;
|
|
TSource[] array;
|
|
if (collection != null)
|
|
{
|
|
if (collection.Count == 0)
|
|
{
|
|
return new TSource[0];
|
|
}
|
|
array = new TSource[collection.Count];
|
|
collection.CopyTo(array, 0);
|
|
return array;
|
|
}
|
|
int num = 0;
|
|
array = new TSource[0];
|
|
foreach (TSource item in source)
|
|
{
|
|
if (num == array.Length)
|
|
{
|
|
if (num == 0)
|
|
{
|
|
array = new TSource[4];
|
|
}
|
|
else
|
|
{
|
|
Array.Resize(ref array, num * 2);
|
|
}
|
|
}
|
|
array[num++] = item;
|
|
}
|
|
if (num != array.Length)
|
|
{
|
|
Array.Resize(ref array, num);
|
|
}
|
|
return array;
|
|
}
|
|
|
|
private static Exception EmptySequence()
|
|
{
|
|
return new InvalidOperationException("Sequence contains no elements");
|
|
}
|
|
|
|
private static Exception NoMatchingElement()
|
|
{
|
|
return new InvalidOperationException("Sequence contains no matching element");
|
|
}
|
|
|
|
private static Exception MoreThanOneElement()
|
|
{
|
|
return new InvalidOperationException("Sequence contains more than one element");
|
|
}
|
|
|
|
private static Exception MoreThanOneMatchingElement()
|
|
{
|
|
return new InvalidOperationException("Sequence contains more than one matching element");
|
|
}
|
|
}
|
|
}
|