#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; namespace Masuit.Tools { public static partial class IEnumerableExtensions { /// /// 遍历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, int maxParallelCount, Func action) { if (source.Any()) { using SemaphoreSlim completeSemphoreSlim = new(1); using SemaphoreSlim taskCountLimitsemaphoreSlim = new(maxParallelCount); await completeSemphoreSlim.WaitAsync(); int runningtaskCount = source.Count(); foreach (var item in source) { await taskCountLimitsemaphoreSlim.WaitAsync(); Task.Run(async () => { try { await action(item).ContinueWith(_ => { Interlocked.Decrement(ref runningtaskCount); if (runningtaskCount == 0) { completeSemphoreSlim.Release(); } }); } finally { taskCountLimitsemaphoreSlim.Release(); } }); } await completeSemphoreSlim.WaitAsync(); } } /// /// 异步foreach /// /// /// /// /// public static Task ForeachAsync(this IEnumerable source, Func action) { return ForAsync(source, (t, _) => action(t)); } /// /// 按字段去重 /// /// /// /// /// /// 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; } /// /// 异步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 Task ForAsync(this IEnumerable source, Func selector) { return Task.WhenAll(source.Select(selector)); } /// /// 取最大值 /// /// /// /// /// /// 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; } } }