using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Core.Common.Utils.Collections
{
public static class EnumerableExtensions
{
///
/// Returns the type of the (first) element in the Enumerable. Returns null if the enumerable is empty.
///
///
///
public static Type GetInnerType(this IEnumerable source)
{
foreach (var item in source)
{
return item.GetType();
}
return null;
}
///
/// Adds elements to enumerable (replaces .Concat(new []{element1, element2 ...}) )
///
/// Type of item
/// Collection to add the elements to
/// Items to add
/// with
public static IEnumerable Plus(this IEnumerable collection, params T[] items)
{
return collection.Concat(items);
}
public static void ForEach(this IEnumerable source, Action action)
{
foreach (var item in source)
{
action(item);
}
}
public static IList AsList(this IEnumerable enumerable)
{
return enumerable as IList ?? enumerable.ToList();
}
//borrowed: http://stackoverflow.com/questions/3907408/dotnet-flatten-a-tree-list-of-lists-with-one-statement
public static IEnumerable Flatten(this IEnumerable source, Func> childrenSelector)
{
foreach (var item in source)
{
yield return item;
foreach (var child in childrenSelector(item).Flatten(childrenSelector))
{
yield return child;
}
}
}
public static void ForEach(this IEnumerable source, Action action)
{
var i = 0;
foreach (var item in source)
{
action(item, i);
i++;
}
}
public static bool HasExactlyOneValue(this IEnumerable values)
{
int i = 0;
foreach (object o in values)
{
i++;
if (i > 1)
{
break;
}
}
return (i == 1);
}
public static IEnumerable> SplitInGroups(this IEnumerable list, int groupSize)
{
if (groupSize <= 0)
{
throw new ArgumentException("GroupSize must be greater than 0", "groupSize");
}
var countSoFar = 0;
var group = new List();
foreach (var elem in list)
{
group.Add(elem);
if (++countSoFar == groupSize)
{
yield return group;
countSoFar = 0;
group = new List();
}
}
if (group.Count > 0)
{
yield return group;
}
}
///
/// Returns values1 except values2.
///
///
///
///
public static IEnumerable Except(this IEnumerable values1, IList values2)
{
foreach (object o in values1)
{
if (!values2.Contains(o))
{
yield return o;
}
}
}
public static string ConvertToString(this IEnumerable values)
{
return String.Join(",", values.Select(v => v.ToString()).ToArray());
}
public static IEnumerable QuickSort(this IEnumerable list)
where T : IComparable
{
if (!list.Any())
{
return Enumerable.Empty();
}
T pivot = (T) list.First();
IEnumerable smaller = list.Where(item => item.CompareTo(pivot) <= 0).QuickSort();
IEnumerable larger = list.Where(item => item.CompareTo(pivot) > 0).QuickSort();
return smaller.Concat(new[]
{
pivot
}).Concat(larger);
}
public static IEnumerable Substract(this IEnumerable index1, IEnumerable index2)
{
var i1 = index1.GetEnumerator();
var i2 = index2.GetEnumerator();
while (i1.MoveNext() && i2.MoveNext())
{
yield return i1.Current - i2.Current;
}
}
public static IEnumerable AddValue(this IEnumerable index1, IEnumerable index2)
{
var i1 = index1.GetEnumerator();
var i2 = index2.GetEnumerator();
while (i1.MoveNext() && i2.MoveNext())
{
yield return i1.Current + i2.Current;
}
}
public static IEnumerable AddValue(this IEnumerable index1, int value)
{
var i1 = index1.GetEnumerator();
while (i1.MoveNext())
{
yield return i1.Current + value;
}
}
public static IEnumerable Substract(this IEnumerable index1, int value)
{
var i1 = index1.GetEnumerator();
while (i1.MoveNext())
{
yield return i1.Current - value;
}
}
// From http://community.bartdesmet.net/blogs/bart/archive/2008/11/03/c-4-0-feature-focus-part-3-intermezzo-linq-s-new-zip-operator.aspx
public static IEnumerable Zip(this IEnumerable first, IEnumerable second, Func func)
{
if (first == null)
{
throw new ArgumentNullException("first");
}
if (second == null)
{
throw new ArgumentNullException("second");
}
if (func == null)
{
throw new ArgumentNullException("func");
}
using (var ie1 = first.GetEnumerator())
{
using (var ie2 = second.GetEnumerator())
{
while (ie1.MoveNext() && ie2.MoveNext())
{
yield return func(ie1.Current, ie2.Current);
}
}
}
}
public static IEnumerable> Zip(this IEnumerable first, IEnumerable second)
{
return first.Zip(second, (f, s) => new Tuple(f, s));
}
public static bool HasUniqueValues(this IEnumerable enumerable)
{
return enumerable.Distinct().Count() == enumerable.Count();
}
public static bool IsMonotonousDescending(this IEnumerable enumerable) where T : IComparable
{
T previousValue = default(T);
foreach (var value in enumerable)
{
if (previousValue != null && !previousValue.Equals(default(T)))
{
if (value.CompareTo(previousValue) > 0)
{
return false; //the next value is smaller than the previous...not monotonous ascending
}
}
previousValue = value;
}
return true;
}
public static bool IsMonotonousAscending(this IEnumerable enumerable) where T : IComparable
{
T previousValue = default(T);
foreach (var value in enumerable)
{
if (previousValue != null && !previousValue.Equals(default(T)))
{
if (value.CompareTo(previousValue) < 0)
{
return false; //the next value is smaller than the previous...not monotonous ascending
}
}
previousValue = value;
}
return true;
} /*
public static void Times(this int times,Action action)
{
for (int i =0;i
/// Returns the number of elements in a sequence.
///
/// A sequence that contains elements to be counted.
/// The number of elements in the input sequence.
/// source is null.
/// The number of elements in source is larger than
///
public static int Count(this IEnumerable source)
{
return Enumerable.Count(source.Cast