CollectionExtension.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. namespace Core.Util.Extension
  7. {
  8. /// <summary>集合扩展</summary>
  9. public static class CollectionExtension
  10. {
  11. /// <summary>
  12. /// 确保某一类型的元素必须位于开始位置
  13. /// </summary>
  14. /// <typeparam name="T"></typeparam>
  15. /// <param name="source"></param>
  16. /// <param name="checkedItem">想要位于首位的元素的类型</param>
  17. /// <returns>调整后的集合</returns>
  18. /// <remarks>
  19. /// 本方法适用于要确认的元素的类型在集合中唯一的情况。
  20. /// </remarks>
  21. public static void EnsureFirstPosition<T>(this IEnumerable<T> source, Type checkedItem)
  22. {
  23. if (source == null)
  24. {
  25. return ;
  26. }
  27. var sourceArray = new List<T>(source);
  28. var itemIndex = sourceArray.FindIndex(m => m.GetType() == checkedItem);
  29. if (itemIndex <= 0) return ;
  30. var changeItem = sourceArray[itemIndex];
  31. sourceArray.RemoveAt(itemIndex);
  32. sourceArray.Insert(0, changeItem);
  33. source= sourceArray;
  34. }
  35. /// <summary>
  36. /// 确保某一类型的元素必须位于末尾位置
  37. /// </summary>
  38. /// <typeparam name="T"></typeparam>
  39. /// <param name="source"></param>
  40. /// <param name="checkedItem">想要位于首位的元素的类型</param>
  41. /// <returns>调整后的集合</returns>
  42. /// <remarks>
  43. /// 本方法适用于要确认的元素的类型在集合中唯一的情况。
  44. /// </remarks>
  45. public static void EnsureLastPosition<T>(this IEnumerable<T> source, Type checkedItem)
  46. {
  47. if (source == null)
  48. {
  49. return ;
  50. }
  51. var sourceArray = new List<T>(source);
  52. var itemIndex = sourceArray.FindIndex(m => m.GetType() == checkedItem);
  53. if (itemIndex == sourceArray.Count-1) return ;
  54. var changeItem = sourceArray[itemIndex];
  55. sourceArray.RemoveAt(itemIndex);
  56. sourceArray.Insert(sourceArray.Count-1, changeItem);
  57. source = sourceArray;
  58. }
  59. /// <summary>
  60. /// 集合转换
  61. /// </summary>
  62. /// <typeparam name="T">对象类型</typeparam>
  63. /// <typeparam name="TResult">转换后的对象</typeparam>
  64. /// <param name="items">对象</param>
  65. /// <param name="transformation">转换表达式</param>
  66. /// <returns></returns>
  67. public static IEnumerable<TResult> ConvertAll<T, TResult>(this IEnumerable<T> items,
  68. Converter<T, TResult> transformation)
  69. {
  70. if (items == null) return null;
  71. var arr = items as T[];
  72. if (arr != null)
  73. {
  74. return Array.ConvertAll(arr, transformation);
  75. }
  76. var list = items as List<T>;
  77. if (list != null)
  78. {
  79. return list.ConvertAll(transformation);
  80. }
  81. return items.Select(_ => transformation(_));
  82. }
  83. /// <summary>
  84. /// Func转Predicate
  85. /// </summary>
  86. /// <typeparam name="T"></typeparam>
  87. /// <param name="source"></param>
  88. /// <returns></returns>
  89. public static Predicate<T> ToPredicate<T>(this Func<T, bool> source)
  90. {
  91. var result = new Predicate<T>(source);
  92. return result;
  93. }
  94. /// <summary>
  95. /// IEnumerable<T>对象的轮询操作
  96. /// </summary>
  97. /// <typeparam name="T"></typeparam>
  98. /// <param name="items"></param>
  99. /// <param name="action"></param>
  100. public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
  101. {
  102. if (items == null)
  103. {
  104. return;
  105. }
  106. var arr = items as T[];
  107. if (arr != null)
  108. {
  109. Array.ForEach(arr, action);
  110. return;
  111. }
  112. var list = items as List<T>;
  113. if (list != null)
  114. {
  115. list.ForEach(action);
  116. return;
  117. }
  118. foreach (var item in items)
  119. {
  120. action(item);
  121. }
  122. }
  123. /// <summary>
  124. /// IEnumerable<T>是否为空
  125. /// </summary>
  126. /// <param name="targer"></param>
  127. /// <returns></returns>
  128. public static bool IsNullOrEmpty(this IEnumerable targer)
  129. {
  130. return targer == null || targer.GetEnumerator().MoveNext() == false;
  131. }
  132. /// <summary>
  133. /// ICollection<T />转换成数组T[]
  134. /// </summary>
  135. public static T[] ToArray<T>(this ICollection<T> collection, int index = 0)
  136. {
  137. if (collection.IsNullOrEmpty()) return null;
  138. var arr = new T[collection.Count];
  139. collection.CopyTo(arr, index);
  140. return arr;
  141. }
  142. /// <summary>把一个列表组合成为一个字符串,默认逗号分隔</summary>
  143. /// <param name="value"></param>
  144. /// <param name="separator">组合分隔符,默认逗号</param>
  145. /// <returns></returns>
  146. public static string Join(this IEnumerable value, string separator = ",")
  147. {
  148. if (value == null) return null;
  149. var sb = new StringBuilder();
  150. foreach (var item in value)
  151. {
  152. sb.Separate(separator).Append(item + "");
  153. }
  154. return sb.ToString();
  155. }
  156. /// <summary>把一个列表组合成为一个字符串,默认逗号分隔</summary>
  157. /// <param name="value"></param>
  158. /// <param name="separator">组合分隔符,默认逗号</param>
  159. /// <param name="func">把对象转为字符串的委托</param>
  160. /// <returns></returns>
  161. public static string Join<T>(this IEnumerable<T> value, string separator = ",", Func<T, string> func = null)
  162. {
  163. if (value == null) return null;
  164. var sb = new StringBuilder();
  165. if (func == null) func = obj => obj + "";
  166. foreach (var item in value)
  167. {
  168. sb.Separate(separator).Append(func(item));
  169. }
  170. return sb.ToString();
  171. }
  172. /// <summary>
  173. /// 在考虑依赖关系的情况下,使用托普法进行排序
  174. /// </summary>
  175. /// <typeparam name="T">要排序的类型.</typeparam>
  176. /// <param name="source">要排序的数据</param>
  177. /// <param name="getDependencies">依赖项查询</param>
  178. /// <returns></returns>
  179. public static List<T> SortByDependencies<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getDependencies)
  180. {
  181. var sorted = new List<T>();
  182. var visited = new Dictionary<T, bool>();
  183. foreach (var item in source)
  184. {
  185. SortByDependenciesVisit(item, getDependencies, sorted, visited);
  186. }
  187. return sorted;
  188. }
  189. private static void SortByDependenciesVisit<T>(T item, Func<T, IEnumerable<T>> getDependencies, List<T> sorted, Dictionary<T, bool> visited)
  190. {
  191. bool inProcess;
  192. var alreadyVisited = visited.TryGetValue(item, out inProcess);
  193. if (alreadyVisited)
  194. {
  195. if (inProcess)
  196. {
  197. throw new ArgumentException("Cyclic dependency found!");
  198. }
  199. }
  200. else
  201. {
  202. visited[item] = true;
  203. var dependencies = getDependencies(item);
  204. if (dependencies != null)
  205. {
  206. foreach (var dependency in dependencies)
  207. {
  208. SortByDependenciesVisit(dependency, getDependencies, sorted, visited);
  209. }
  210. }
  211. visited[item] = false;
  212. sorted.Add(item);
  213. }
  214. }
  215. }
  216. }