CloudBuilder/CloudBuilder.Core/Extensions/EnumerableExtensions.cs
owenchen 1c0c83af5f ow
2026-05-12 10:09:31 +08:00

200 lines
8.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudBuilder.Core.Extensions
{
/// <summary>
/// Enumerable集合扩展方法
/// </summary>
public static class EnumerableExtensions
{
/// <summary>
/// 打乱一个集合的项顺序
/// </summary>
public static IEnumerable<TSource> Shuffle<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
return source.OrderBy(m => Guid.NewGuid());
}
/// <summary>
/// 将集合展开并分别转换成字符串,再以指定的分隔符衔接,拼成一个字符串返回。默认分隔符为逗号
/// </summary>
/// <param name="collection"> 要处理的集合 </param>
/// <param name="separator"> 分隔符,默认为逗号 </param>
/// <returns> 拼接后的字符串 </returns>
public static string ExpandAndToString<T>(this IEnumerable<T> collection, string separator = ",")
{
return collection.ExpandAndToString(t => t?.ToString(), separator);
}
/// <summary>
/// 循环集合的每一项,调用委托生成字符串,返回合并后的字符串。默认分隔符为逗号
/// </summary>
/// <param name="collection">待处理的集合</param>
/// <param name="itemFormatFunc">单个集合项的转换委托</param>
/// <param name="separator">分隔符,默认为逗号</param>
/// <typeparam name="T">泛型类型</typeparam>
/// <returns></returns>
public static string ExpandAndToString<T>(this IEnumerable<T> collection, Func<T, string> itemFormatFunc, string separator = ",")
{
collection = collection as IList<T> ?? collection.ToList();
if (!collection.Any())
{
return string.Empty;
}
StringBuilder sb = new StringBuilder();
int i = 0;
int count = collection.Count();
foreach (T t in collection)
{
if (i == count - 1)
{
sb.Append(itemFormatFunc(t));
}
else
{
sb.Append(itemFormatFunc(t) + separator);
}
i++;
}
return sb.ToString();
}
/// <summary>
/// 集合是否为空
/// </summary>
/// <param name="collection"> 要处理的集合 </param>
/// <typeparam name="T"> 动态类型 </typeparam>
/// <returns> 为空返回True不为空返回False </returns>
public static bool IsEmpty<T>(this IEnumerable<T> collection)
{
collection = collection as IList<T> ?? collection.ToList();
return !collection.Any();
}
/// <summary>
/// 根据第三方条件是否为真来决定是否执行指定条件的查询
/// </summary>
/// <param name="source"> 要查询的源 </param>
/// <param name="predicate"> 查询条件 </param>
/// <param name="condition"> 第三方条件 </param>
/// <typeparam name="T"> 动态类型 </typeparam>
/// <returns> 查询的结果 </returns>
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool condition)
{
source = source as IList<T> ?? source.ToList();
return condition ? source.Where(predicate) : source;
}
/// <summary>
/// 将字符串集合按指定前缀排序
/// </summary>
public static IEnumerable<T> OrderByPrefixes<T>(this IEnumerable<T> source, Func<T, string> keySelector, params string[] prefixes)
{
List<T> all = source.OrderBy(keySelector).ToList();
List<T> result = new List<T>();
foreach (string prefix in prefixes)
{
List<T> tmpList = all.Where(m => keySelector(m).StartsWith(prefix)).OrderBy(keySelector).ToList();
all = all.Except(tmpList).ToList();
result.AddRange(tmpList);
}
result.AddRange(all);
return result;
}
/// <summary>
/// 根据指定条件返回集合中不重复的元素
/// </summary>
/// <typeparam name="T">动态类型</typeparam>
/// <typeparam name="TKey">动态筛选条件类型</typeparam>
/// <param name="source">要操作的源</param>
/// <param name="keySelector">重复数据筛选条件</param>
/// <returns>不重复元素的集合</returns>
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector)
{
source = source as IList<T> ?? source.ToList();
return source.GroupBy(keySelector).Select(group => group.First());
}
/// <summary>
/// 把<see cref="IEnumerable{T}"/>集合按指定字段与排序方式进行排序
/// </summary>
/// <typeparam name="T">集合项类型</typeparam>
/// <param name="source">要排序的数据集</param>
/// <param name="propertyName">排序属性名</param>
/// <param name="sortDirection">排序方向</param>
/// <returns>排序后的数据集</returns>
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> source,
string propertyName,
ListSortDirection sortDirection = ListSortDirection.Ascending)
{
return CollectionPropertySorter<T>.OrderBy(source, propertyName, sortDirection);
}
/// <summary>
/// 把<see cref="IEnumerable{T}"/>集合按指定字段排序条件进行排序
/// </summary>
/// <typeparam name="T">动态类型</typeparam>
/// <param name="source">要排序的数据集</param>
/// <param name="sortCondition">列表字段排序条件</param>
/// <returns></returns>
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> source, SortCondition sortCondition)
{
return source.OrderBy(sortCondition.SortField, sortCondition.ListSortDirection);
}
/// <summary>
/// 把<see cref="IEnumerable{T}"/>集合按指定字段排序条件进行排序
/// </summary>
/// <typeparam name="T">动态类型</typeparam>
/// <param name="source">要排序的数据集</param>
/// <param name="sortCondition">列表字段排序条件</param>
/// <returns></returns>
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> source, SortCondition<T> sortCondition)
{
return source.OrderBy(sortCondition.SortField, sortCondition.ListSortDirection);
}
/// <summary>
/// 把<see cref="IOrderedQueryable{T}"/>集合继续按指定字段排序方式进行排序
/// </summary>
/// <typeparam name="T">动态类型</typeparam>
/// <param name="source">要排序的数据集</param>
/// <param name="propertyName">排序属性名</param>
/// <param name="sortDirection">排序方向</param>
/// <returns></returns>
public static IOrderedEnumerable<T> ThenBy<T>(this IOrderedEnumerable<T> source,
string propertyName,
ListSortDirection sortDirection = ListSortDirection.Ascending)
{
propertyName.CheckNotNullOrEmpty("propertyName");
return CollectionPropertySorter<T>.ThenBy(source, propertyName, sortDirection);
}
/// <summary>
/// 把<see cref="IOrderedEnumerable{T}"/>集合继续指定字段排序方式进行排序
/// </summary>
/// <typeparam name="T">动态类型</typeparam>
/// <param name="source">要排序的数据集</param>
/// <param name="sortCondition">列表字段排序条件</param>
/// <returns></returns>
public static IOrderedEnumerable<T> ThenBy<T>(this IOrderedEnumerable<T> source, SortCondition sortCondition)
{
return source.ThenBy(sortCondition.SortField, sortCondition.ListSortDirection);
}
}
}