#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));
}
}
}