using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sony.Filtr.Contracts.Entities; namespace Sony.Filtr.Utility.Extensions { public static class IEnumerableExt { public static T Mean(this IEnumerable source) { return source.OrderBy(s => s).ElementAt(source.Count() / 2); } public static bool TryFirst(this IEnumerable seq, Func filter, out T result) { result = default(T); foreach (var item in seq) { if (filter(item)) { result = item; return true; } } return false; } public static void ForEachMy(this IEnumerable source, Action action) { foreach (var item in source) { action(item); } } // usage: someObject.AsEnumerable(); public static IEnumerable AsEnumerable(this T item) { yield return item; } public static IEnumerable> ItemIndex(this IEnumerable source) { return source.Select((item, index) => new ItemIndex { Item = item, Index = index, }); } public static IEnumerable FilterNull(this IEnumerable source) { return source.Where(i => i != null); } public static IEnumerable FilterNull(this IEnumerable source) where T : struct { return source.Where(i => i.HasValue).Select(i=> i.Value); } public static Task ForEachAsync(this IEnumerable source, int dop, Func body, IProgress progress = null) { return Task.WhenAll( from partition in Partitioner.Create(source).GetPartitions(dop) select Task.Run(async delegate { using (partition) { while (partition.MoveNext()) { await body(partition.Current); progress?.Report(1); } } })); } public static PaginatedContent Paginate(this IEnumerable items, int limit, int offset, int total) { IEnumerable filteredObjects = items; filteredObjects = filteredObjects.Skip(offset); filteredObjects = filteredObjects.Take(limit); return new PaginatedContent() { Items = filteredObjects.ToList(), Pagination = new Pagination() { Total = total, Limit = limit, Offset = offset } }; } public static PaginatedContent ExtendForPagination(this IEnumerable items, int limit, int offset, long total) { if (total == 0) { total = items.Count(); } return new PaginatedContent() { Items = items.ToList(), Pagination = new Pagination() { Total = total, Limit = limit, Offset = offset } }; } public static PaginatedContent Paginate(this IList items, int limit, int offset) { var total = items.Count(); return items.Paginate(limit, offset, total); } public static IEnumerable SelectWithPrevious(this IEnumerable source, Func projection) { using (var iterator = source.GetEnumerator()) { if (!iterator.MoveNext()) { yield break; } TSource previous = iterator.Current; while (iterator.MoveNext()) { yield return projection(previous, iterator.Current); previous = iterator.Current; } } } public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, OrderByDirection direction) { return direction == OrderByDirection.Asc ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector); } public static bool IsNullOrEmpty(this IEnumerable items) { if (items == null || !items.Any()) { return true; } return false; } public static IEnumerable> SplitOnBatches(this IEnumerable source, int itemsInBatch) { return source .Select((item, index) => new { item, index }) .GroupBy(pair => pair.index / itemsInBatch) .Select(group => group.Select(g => g.item)) .ToArray(); } public static bool StartsWith(this IEnumerable source, IEnumerable x, Func areEqual) { if (source.Count() < x.Count()) { return false; } for (int i = 0; i < x.Count(); ++i) { T sourceElement = source.ElementAt(i); T xElement = x.ElementAt(i); if (areEqual(sourceElement, xElement) == false) { return false; } } return true; } public static Nullable FirstNonMatchIndex(this IEnumerable source, IEnumerable x, Func equalFunc) { for (int i = 0; i < Math.Min(source.Count(), x.Count()); ++i) { T sourceElement = source.ElementAt(i); T xElement = x.ElementAt(i); bool areEqual = equalFunc(sourceElement, xElement); if (areEqual == false) { return i; } } return null; } } public enum OrderByDirection { Asc = 0, Desc = 1, } public class ItemIndex { public T Item { get; internal set; } public int Index { get; internal set; } } }