using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; namespace IRaCIS.Core.Infrastructure.Extention { public static partial class IEnumerableExtensions { ///// ///// 按字段去重 ///// ///// ///// ///// ///// ///// //public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) //{ // var hash = new HashSet(); // return source.Where(p => hash.Add(keySelector(p))); //} /// /// 添加多个元素 /// /// /// /// public static void AddRange(this ICollection @this, params T[] values) { foreach (var obj in values) { @this.Add(obj); } } /// /// 添加符合条件的多个元素 /// /// /// /// /// public static void AddRangeIf(this ICollection @this, Func predicate, params T[] values) { foreach (var obj in values) { if (predicate(obj)) { @this.Add(obj); } } } /// /// 添加不重复的元素 /// /// /// /// public static void AddRangeIfNotContains(this ICollection @this, params T[] values) { foreach (T obj in values) { if (!@this.Contains(obj)) { @this.Add(obj); } } } /// /// 移除符合条件的元素 /// /// /// /// public static void RemoveWhere(this ICollection @this, Func @where) { foreach (var obj in @this.Where(where).ToList()) { @this.Remove(obj); } } /// /// 在元素之后添加元素 /// /// /// /// 条件 /// 值 public static void InsertAfter(this IList list, Func condition, T value) { foreach (var item in list.Select((item, index) => new { item, index }).Where(p => condition(p.item)).OrderByDescending(p => p.index)) { if (item.index + 1 == list.Count) { list.Add(value); } else { list.Insert(item.index + 1, value); } } } /// /// 在元素之后添加元素 /// /// /// /// 索引位置 /// 值 public static void InsertAfter(this IList list, int index, T value) { foreach (var item in list.Select((v, i) => new { Value = v, Index = i }).Where(p => p.Index == index).OrderByDescending(p => p.Index)) { if (item.Index + 1 == list.Count) { list.Add(value); } else { list.Insert(item.Index + 1, value); } } } /// /// 转HashSet /// /// /// /// /// /// public static HashSet ToHashSet(this IEnumerable source, Func selector) { var set = new HashSet(); set.UnionWith(source.Select(selector)); return set; } /// /// 遍历IEnumerable /// /// /// 回调方法 /// public static void ForEach(this IEnumerable objs, Action action) { foreach (var o in objs) { action(o); } } /// /// 异步foreach /// /// /// /// 最大并行数 /// /// /// public static async Task ForeachAsync(this IEnumerable source, Func action, int maxParallelCount, CancellationToken cancellationToken = default) { var list = new List(); foreach (var item in source) { if (cancellationToken.IsCancellationRequested) { return; } list.Add(action(item)); if (list.Count >= maxParallelCount) { await Task.WhenAll(list); list.Clear(); } } await Task.WhenAll(list); } /// /// 异步foreach /// /// /// /// /// public static Task ForeachAsync(this IEnumerable source, Func action, CancellationToken cancellationToken = default) { return ForeachAsync(source, action, source.Count(), cancellationToken); } /// /// 异步Select /// /// /// /// /// /// public static Task SelectAsync(this IEnumerable source, Func> selector) { return Task.WhenAll(source.Select(selector)); } /// /// 异步Select /// /// /// /// /// /// public static Task SelectAsync(this IEnumerable source, Func> selector) { return Task.WhenAll(source.Select(selector)); } /// /// 异步For /// /// /// /// /// 最大并行数 /// 取消口令 /// public static async Task ForAsync(this IEnumerable source, Func selector, int maxParallelCount, CancellationToken cancellationToken = default) { var list = new List(); int index = 0; foreach (var item in source) { if (cancellationToken.IsCancellationRequested) { return; } list.Add(selector(item, index++)); if (list.Count >= maxParallelCount) { await Task.WhenAll(list); list.Clear(); } } await Task.WhenAll(list); } /// /// 异步For /// /// /// /// /// 取消口令 /// public static Task ForAsync(this IEnumerable source, Func selector, CancellationToken cancellationToken = default) { return ForAsync(source, selector, source.Count(), cancellationToken); } /// /// 取最大值 /// /// /// /// /// /// public static TResult MaxOrDefault(this IQueryable source, Expression> selector) => source.Select(selector).DefaultIfEmpty().Max(); /// /// 取最大值 /// /// /// /// /// /// /// public static TResult MaxOrDefault(this IQueryable source, Expression> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Max(); /// /// 取最大值 /// /// /// /// public static TSource MaxOrDefault(this IQueryable source) => source.DefaultIfEmpty().Max(); /// /// 取最大值 /// /// /// /// /// public static TSource MaxOrDefault(this IQueryable source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Max(); /// /// 取最大值 /// /// /// /// /// /// /// public static TResult MaxOrDefault(this IEnumerable source, Func selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Max(); /// /// 取最大值 /// /// /// /// /// /// public static TResult MaxOrDefault(this IEnumerable source, Func selector) => source.Select(selector).DefaultIfEmpty().Max(); /// /// 取最大值 /// /// /// /// public static TSource MaxOrDefault(this IEnumerable source) => source.DefaultIfEmpty().Max(); /// /// 取最大值 /// /// /// /// /// public static TSource MaxOrDefault(this IEnumerable source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Max(); /// /// 取最小值 /// /// /// /// /// /// public static TResult MinOrDefault(this IQueryable source, Expression> selector) => source.Select(selector).DefaultIfEmpty().Min(); /// /// 取最小值 /// /// /// /// /// /// /// public static TResult MinOrDefault(this IQueryable source, Expression> selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Min(); /// /// 取最小值 /// /// /// /// public static TSource MinOrDefault(this IQueryable source) => source.DefaultIfEmpty().Min(); /// /// 取最小值 /// /// /// /// /// public static TSource MinOrDefault(this IQueryable source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Min(); /// /// 取最小值 /// /// /// /// /// /// public static TResult MinOrDefault(this IEnumerable source, Func selector) => source.Select(selector).DefaultIfEmpty().Min(); /// /// 取最小值 /// /// /// /// /// /// /// public static TResult MinOrDefault(this IEnumerable source, Func selector, TResult defaultValue) => source.Select(selector).DefaultIfEmpty(defaultValue).Min(); /// /// 取最小值 /// /// /// /// public static TSource MinOrDefault(this IEnumerable source) => source.DefaultIfEmpty().Min(); /// /// 取最小值 /// /// /// /// /// public static TSource MinOrDefault(this IEnumerable source, TSource defaultValue) => source.DefaultIfEmpty(defaultValue).Min(); ///// ///// 标准差 ///// ///// ///// ///// ///// //public static TResult StandardDeviation(this IEnumerable source, Func selector) where TResult : IConvertible //{ // return StandardDeviation(source.Select(t => selector(t).ConvertTo())).ConvertTo(); //} ///// ///// 标准差 ///// ///// ///// ///// //public static T StandardDeviation(this IEnumerable source) where T : IConvertible //{ // return StandardDeviation(source.Select(t => t.ConvertTo())).ConvertTo(); //} /// /// 标准差 /// /// /// public static double StandardDeviation(this IEnumerable source) { double result = 0; int count = source.Count(); if (count > 1) { double avg = source.Average(); double sum = source.Sum(d => (d - avg) * (d - avg)); result = Math.Sqrt(sum / count); } return result; } /// /// 随机排序 /// /// /// /// public static IOrderedEnumerable OrderByRandom(this IEnumerable source) { return source.OrderBy(_ => Guid.NewGuid()); } /// /// 序列相等 /// /// /// /// /// /// public static bool SequenceEqual(this IEnumerable first, IEnumerable second, Func condition) { if (first is ICollection source1 && second is ICollection source2) { if (source1.Count != source2.Count) { return false; } if (source1 is IList list1 && source2 is IList list2) { int count = source1.Count; for (int index = 0; index < count; ++index) { if (!condition(list1[index], list2[index])) { return false; } } return true; } } using IEnumerator enumerator1 = first.GetEnumerator(); using IEnumerator enumerator2 = second.GetEnumerator(); while (enumerator1.MoveNext()) { if (!enumerator2.MoveNext() || !condition(enumerator1.Current, enumerator2.Current)) { return false; } } return !enumerator2.MoveNext(); } /// /// 序列相等 /// /// /// /// /// /// /// public static bool SequenceEqual(this IEnumerable first, IEnumerable second, Func condition) { if (first is ICollection source1 && second is ICollection source2) { if (source1.Count != source2.Count) { return false; } if (source1 is IList list1 && source2 is IList list2) { int count = source1.Count; for (int index = 0; index < count; ++index) { if (!condition(list1[index], list2[index])) { return false; } } return true; } } using IEnumerator enumerator1 = first.GetEnumerator(); using IEnumerator enumerator2 = second.GetEnumerator(); while (enumerator1.MoveNext()) { if (!enumerator2.MoveNext() || !condition(enumerator1.Current, enumerator2.Current)) { return false; } } return !enumerator2.MoveNext(); } /// /// 对比两个集合哪些是新增的、删除的、修改的 /// /// /// /// /// /// 对比因素属性 /// 对比因素属性 /// public static (List adds, List remove, List updates) CompareChanges(this IEnumerable olds, IEnumerable news, Func key1Selector, Func key2Selector) { return (news.Where(c => olds.All(m => key1Selector(m) != key2Selector(c))).ToList(), olds.Where(m => news.All(c => key2Selector(c) != key1Selector(m))).ToList(), olds.Where(m => news.Any(c => key1Selector(m) == key2Selector(c))).ToList()); } /// /// 对比两个集合哪些是新增的、删除的、修改的 /// /// /// /// /// 对比因素属性 /// public static (List adds, List remove, List updates) CompareChanges(this IEnumerable olds, IEnumerable news, Func keySelector) { return (news.Where(c => olds.All(m => keySelector(m) != keySelector(c))).ToList(), olds.Where(m => news.All(c => keySelector(c) != keySelector(m))).ToList(), olds.Where(m => news.Any(c => keySelector(m) == keySelector(c))).ToList()); } } }