CollectionExtension.cs 8.0 KB

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