PageRenderTime 814ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/DSSharp.List.cs

http://github.com/fredericaltorres/DynamicSugarNet
C# | 409 lines | 190 code | 56 blank | 163 comment | 25 complexity | ac67b2961d18831821a08eaeb3fbefbe MD5 | raw file
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.IO;
  6. using System.Collections;
  7. #if !MONOTOUCH
  8. using System.Dynamic;
  9. #endif
  10. using System.Reflection;
  11. namespace DynamicSugar {
  12. /// <summary>
  13. /// Dynamic Sharp Helper Class, dedicated methods to work with list
  14. /// </summary>
  15. public static partial class DS {
  16. public static class ListHelper {
  17. /// <summary>
  18. /// Return in a List Of T, call to the instance of the default method
  19. /// instance[0], instance[1], instance[2],...
  20. /// </summary>
  21. /// <param name="instance"></param>
  22. /// <returns></returns>
  23. private static List<object> get_Items(object instance) {
  24. int count = (int)ReflectionHelper.GetProperty(instance, "Count");
  25. List<Object> lo = new List<object>();
  26. for (int i = 0; i < count; i++)
  27. lo.Add(ReflectionHelper.ExecuteMethod(instance, "get_Item", i));
  28. return lo;
  29. }
  30. /// <summary>
  31. /// Return a list of string read from a text file.
  32. /// Each line of the text file is an entry in a list.
  33. /// </summary>
  34. /// <param name="fileName">The filename to load</param>
  35. /// <returns>A List Of String</returns>
  36. private static List<string> __FromFileAsListOfString(string fileName) {
  37. List<string> l = new List<string>();
  38. if(System.IO.File.Exists(fileName)){
  39. var text = System.IO.File.ReadAllText(fileName);
  40. string [] sepa = new string [] { Environment.NewLine };
  41. var lines = text.Split(sepa, StringSplitOptions.None);
  42. foreach(var e in lines)
  43. l.Add(e);
  44. }
  45. return l;
  46. }
  47. /// <summary>
  48. /// Save the context of a List Of T to a file
  49. /// </summary>
  50. /// <typeparam name="T"></typeparam>
  51. /// <param name="l">The list</param>
  52. /// <param name="fileName">The file name</param>
  53. /// <param name="create">If true create the file, else append to the file if the file already exist</param>
  54. public static void ToFile<T>(List<T> l, string fileName, bool create = false) {
  55. System.Text.StringBuilder b = new StringBuilder(1024);
  56. foreach(var s in l){
  57. b.Append(s.ToString()).AppendLine();
  58. }
  59. if((create)&&(System.IO.File.Exists(fileName))) System.IO.File.Delete(fileName);
  60. var t = b.ToString();
  61. if(t.EndsWith(Environment.NewLine))
  62. t = t.Substring(0, t.Length-System.Environment.NewLine.Length);
  63. if(System.IO.File.Exists(fileName))
  64. System.IO.File.AppendAllText(fileName, t);
  65. else
  66. System.IO.File.WriteAllText(fileName, t);
  67. }
  68. /// <summary>
  69. /// Return true if the list l contains the element v
  70. /// </summary>
  71. /// <typeparam name="T"></typeparam>
  72. /// <param name="l"></param>
  73. /// <param name="v"></param>
  74. /// <returns></returns>
  75. public static bool Include<T>(List<T> l, T v) {
  76. var tmpL = new List<T>();
  77. tmpL.Add(v);
  78. return DS.ListHelper.Include(l, tmpL);
  79. }
  80. /// <summary>
  81. /// Return true if the list of elements from l2 are all contained
  82. /// in the list l
  83. /// </summary>
  84. /// <typeparam name="T"></typeparam>
  85. /// <param name="l"></param>
  86. /// <param name="l2"></param>
  87. /// <returns></returns>
  88. public static bool Include<T>(List<T> l, List<T> l2) {
  89. foreach(var i in l2) if(!l.Contains(i)) return false;
  90. return true;
  91. }
  92. /// <summary>
  93. /// Filter out element from a List Of T based on Func.
  94. /// </summary>
  95. /// <typeparam name="T"></typeparam>
  96. /// <param name="l"></param>
  97. /// <param name="f">A func that can be implemented as lambda expression</param>
  98. /// <returns></returns>
  99. public static List<T> Reject<T>(List<T> l, Func<T, bool> f) {
  100. var lr = new List<T>();
  101. foreach (var e in l)
  102. if (!f(e))
  103. lr.Add(e);
  104. return lr;
  105. }
  106. /// <summary>
  107. /// Read a List Of T from a file
  108. /// </summary>
  109. /// <typeparam name="T"></typeparam>
  110. /// <param name="fileName"></param>
  111. /// <returns></returns>
  112. public static List<T> FromFile<T>(string fileName) {
  113. var l = new List<T>();
  114. List<string> ll = __FromFileAsListOfString(fileName);
  115. foreach(var s in ll)
  116. l.Add((T)Convert.ChangeType(s, typeof(T)));
  117. return l;
  118. }
  119. /// <summary>
  120. /// Extract from a list of a instance, the value of a specific property and
  121. /// return the value in a List Of T
  122. /// </summary>
  123. /// <typeparam name="T0"></typeparam>
  124. /// <typeparam name="T1"></typeparam>
  125. /// <param name="l"></param>
  126. /// <param name="propertyOrFunction"></param>
  127. /// <returns></returns>
  128. public static List<T0> Pluck<T0, T1>(List<T1> l, string propertyOrFunction) {
  129. List<T0> l1 = new List<T0>();
  130. bool isMethod = propertyOrFunction.EndsWith("()");
  131. if(isMethod)
  132. propertyOrFunction = propertyOrFunction.Substring(0, propertyOrFunction.Length-System.Environment.NewLine.Length);
  133. foreach(var i in l){
  134. try{
  135. object value = null;
  136. if(isMethod ){
  137. value = DynamicSugar.ReflectionHelper.ExecuteMethod(i, propertyOrFunction);
  138. }
  139. else{
  140. value = DynamicSugar.ReflectionHelper.GetProperty(i, propertyOrFunction);
  141. }
  142. T0 v = (T0)Convert.ChangeType(value, typeof(T0));
  143. l1.Add(v);
  144. }
  145. catch{}
  146. }
  147. return l1;
  148. }
  149. /// <summary>
  150. /// Return a List Of T without the first element
  151. /// </summary>
  152. /// <typeparam name="T"></typeparam>
  153. /// <param name="l"></param>
  154. /// <returns></returns>
  155. public static List<T> Rest<T>(List<T> l) {
  156. var l1 = DS.ListHelper.Clone(l);
  157. l1.RemoveAt(0);
  158. return l1;
  159. }
  160. /// <summary>
  161. /// Return the first element of a List Of T
  162. /// </summary>
  163. /// <typeparam name="T"></typeparam>
  164. /// <param name="l"></param>
  165. /// <returns></returns>
  166. public static T First<T>(List<T> l) {
  167. if(l.Count>0)
  168. return l[0];
  169. else
  170. throw new DynamicSugarSharpException("Empty list cannot return first element");
  171. }
  172. /// <summary>
  173. /// Return the last element of a List Of T
  174. /// </summary>
  175. /// <typeparam name="T"></typeparam>
  176. /// <param name="l"></param>
  177. /// <returns></returns>
  178. public static T Last<T>(List<T> l) {
  179. if(l.Count>0)
  180. return l[l.Count-1];
  181. else
  182. throw new DynamicSugarSharpException("Empty list cannot return first element");
  183. }
  184. /// <summary>
  185. /// Merge to List Of T
  186. /// </summary>
  187. /// <typeparam name="T"></typeparam>
  188. /// <param name="l1"></param>
  189. /// <param name="l2"></param>
  190. /// <param name="unique"></param>
  191. /// <returns></returns>
  192. public static List<T> Merge<T>(List<T> l1, List<T> l2, bool unique = true) {
  193. var lr = new List<T>();
  194. if(unique){
  195. foreach (var e in l1)
  196. lr.Add(e);
  197. foreach (var e in l2)
  198. if(!lr.Contains(e))
  199. lr.Add(e);
  200. }
  201. else{
  202. foreach (var e in l1)
  203. lr.Add(e);
  204. foreach (var e in l2)
  205. lr.Add(e);
  206. }
  207. return lr;
  208. }
  209. /// <summary>
  210. ///
  211. /// </summary>
  212. /// <param name="l"></param>
  213. /// <param name="f"></param>
  214. /// <returns></returns>
  215. public static T Inject<T>(List<T> l, Func<T,T,T> f) {
  216. T v = default(T);
  217. foreach (var e in l)
  218. v = f(e, v);
  219. return v;
  220. }
  221. /// <summary>
  222. /// Format a List Of T, with default format parameters
  223. /// </summary>
  224. /// <typeparam name="T"></typeparam>
  225. /// <param name="l"></param>
  226. /// <returns></returns>
  227. public static string Format<T>(List<T> l) {
  228. return Format<T>(l, "{0}");
  229. }
  230. /// <summary>
  231. /// Format a List Of T
  232. /// </summary>
  233. /// <typeparam name="T"></typeparam>
  234. /// <param name="l"></param>
  235. /// <param name="format"></param>
  236. /// <param name="separator"></param>
  237. /// <param name="preFix"></param>
  238. /// <param name="postFix"></param>
  239. /// <returns></returns>
  240. public static string Format<T>(List<T> l, string format, string separator = ", ", string preFix = "", string postFix = "") {
  241. System.Text.StringBuilder b = new StringBuilder(1024);
  242. foreach (var e in l) {
  243. b.AppendFormat(format, ExtendedFormat.FormatValue(e));
  244. b.Append(separator);
  245. }
  246. string r = b.ToString();
  247. if (r.EndsWith(separator))
  248. r = r.Substring(0, r.Length - separator.Length);
  249. return preFix + r + postFix;
  250. }
  251. /// <summary>
  252. /// Apply a Func to all the element of a List Of T and return the result
  253. /// in another List Of T
  254. /// </summary>
  255. /// <typeparam name="T"></typeparam>
  256. /// <param name="l"></param>
  257. /// <param name="f"></param>
  258. /// <returns></returns>
  259. //public static List<T> Map<T>(List<T> l, Func<T, T> f) {
  260. public static List<TResult> Map<TSource, TResult>(List<TSource> source, Func<TSource, TResult> selector){
  261. return source.Select(selector).ToList();
  262. }
  263. /// <summary>
  264. /// Assert that 2 List Of T are equal
  265. /// </summary>
  266. /// <typeparam name="T"></typeparam>
  267. /// <param name="l1"></param>
  268. /// <param name="l2"></param>
  269. public static void AssertListEqual<T>(List<T> l1, List<T> l2) {
  270. if (!Identical(l1, l2)) {
  271. throw new DynamicSugarSharpException(String.Format("List are not equal L1:'{0}', L2:'{1}'", DS.ListHelper.Format(l1), DS.ListHelper.Format(l2)));
  272. }
  273. }
  274. /// <summary>
  275. /// Return true is 2 List Of T are identical
  276. /// </summary>
  277. /// <typeparam name="T"></typeparam>
  278. /// <param name="l1"></param>
  279. /// <param name="l2"></param>
  280. /// <returns></returns>
  281. public static bool Identical<T>(List<T> l1, List<T> l2) {
  282. if (l1.Count != l2.Count) return false;
  283. for (int i = 0; i < l1.Count; i++) {
  284. T t1 = l1[i];
  285. T t2 = l2[i];
  286. if ((t1 == null) && (t2 == null)) continue;
  287. if (!t1.Equals(t2)) return false;
  288. }
  289. return true;
  290. }
  291. /// <summary>
  292. /// Return the intersection of 2 List Of T
  293. /// </summary>
  294. /// <typeparam name="T"></typeparam>
  295. /// <param name="l1"></param>
  296. /// <param name="l2"></param>
  297. /// <returns></returns>
  298. public static List<T> Intersection<T>(List<T> l1, List<T> l2) {
  299. return l1.Intersect(l2).ToList();
  300. }
  301. /// <summary>
  302. /// Add to 2 List Of T together and return the result as a brand new list
  303. /// </summary>
  304. /// <typeparam name="T"></typeparam>
  305. /// <param name="l1"></param>
  306. /// <param name="l2"></param>
  307. /// <returns></returns>
  308. public static List<T> Add<T>(List<T> l1, List<T> l2) {
  309. List<T> l = Clone(l1);
  310. foreach(var e in l2)
  311. l.Add(e);
  312. return l;
  313. }
  314. /// <summary>
  315. /// Substract the element of the List Of T l2 from the List Of T l1
  316. /// </summary>
  317. /// <typeparam name="T"></typeparam>
  318. /// <param name="l1"></param>
  319. /// <param name="l2"></param>
  320. /// <returns></returns>
  321. public static List<T> Substract<T>(List<T> l1, List<T> l2) {
  322. return l1.Except(l2).ToList();
  323. }
  324. /// <summary>
  325. /// Clone a List Of T
  326. /// </summary>
  327. /// <typeparam name="T"></typeparam>
  328. /// <param name="l1"></param>
  329. /// <returns></returns>
  330. public static List<T> Clone<T>(List<T> l1) {
  331. var l = new List<T>();
  332. foreach(var e in l1)
  333. l.Add(e);
  334. return l;
  335. }
  336. /// <summary>
  337. /// Return a List Of T without a set of elements
  338. /// </summary>
  339. /// <typeparam name="T"></typeparam>
  340. /// <param name="l1"></param>
  341. /// <param name="l2"></param>
  342. /// <returns></returns>
  343. public static List<T> Without<T>(List<T> l1, List<T> l2) {
  344. List<T> l = DS.ListHelper.Clone(l1);
  345. for (int i = 0; i < l2.Count; i++) {
  346. var e = l2[i];
  347. if(l.Contains(e)) l.Remove(e);
  348. }
  349. return l;
  350. }
  351. }
  352. }
  353. }