#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Masuit.Tools { public static partial class IEnumerableExtensions { #region SyncForEach /// /// 遍历IEnumerable /// /// /// 回调方法 /// public static void ForEach(this IEnumerable objs, Action action) { foreach (var o in objs) { action(o); } } #endregion SyncForEach #region AsyncForEach public static async Task ForeachAsync(this IEnumerable source, int maxParallelCount, Func action) { 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(task => { Interlocked.Decrement(ref runningtaskCount); if (runningtaskCount == 0) { completeSemphoreSlim.Release(); } }); } finally { taskCountLimitsemaphoreSlim.Release(); } }); } await completeSemphoreSlim.WaitAsync(); } public static async Task ForeachAsync(this IEnumerable source, Func action) { await ForeachAsync(source, source.Count(), action); } #endregion AsyncForEach /// /// 按字段去重 /// /// /// /// /// /// 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 async Task> SelectAsync(this IEnumerable source, Func> selector) { return await Task.WhenAll(source.Select(selector)); } } }