PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/adinetz/runtime/CBucks.Common/ArrOps.cs

#
C# | 644 lines | 357 code | 36 blank | 251 comment | 139 complexity | f4c63abb134e5eb0e3a0eba885e54a09 MD5 | raw file
Possible License(s): AGPL-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Wintellect.PowerCollections;
  5. namespace CBucks.Common {
  6. public delegate bool DoublePred<T1, T2>(T1 a, T2 b);
  7. public delegate T3 Transform<T1, T2, T3>(T1 a, T2 b);
  8. /// <summary>
  9. /// Contains common array operations
  10. /// </summary>
  11. public static class ArrOps {
  12. /// <summary>
  13. /// Checks whether the specified arrays are equal, i.e., contain equal
  14. /// components and are of same length.
  15. /// </summary>
  16. /// <typeparam name="T"> The first array </typeparam>
  17. /// <param name="a"> The first array </param>
  18. /// <param name="b"> The second array </param>
  19. /// <returns> True if they are equal and false if not </returns>
  20. public static bool equal<T>(T[] a, T[] b) {
  21. if(null == a || null == b)
  22. return null == a && null == b;
  23. if(a.Length != b.Length)
  24. return false;
  25. int n = a.Length;
  26. for(int i = 0; i < n; i++)
  27. if(!object.Equals(a[i], b[i]))
  28. return false;
  29. return true;
  30. } // end of equal<T>
  31. /// <summary>
  32. /// Gets the product of all array values and 1 if the array is empty
  33. /// </summary>
  34. /// <param name="arr"> The array </param>
  35. /// <returns> The resulting product </returns>
  36. public static int prod(params int[] arr) {
  37. int p = 1;
  38. foreach(int i in arr)
  39. p *= i;
  40. return p;
  41. } // end of prod()
  42. /// <summary>
  43. /// Transforms an array into a 2D array of the specified size,
  44. /// </summary>
  45. /// <typeparam name="T"> The type of the array to transform </typeparam>
  46. /// <param name="arr"> The source array </param>
  47. /// <param name="s"> The size of the resulting 2D array </param>
  48. /// <returns> The resulting array </returns>
  49. public static T[,] to2DArray<T>(Array arr, int s) {
  50. T[,] arr2 = new T[s, s];
  51. // copy array values
  52. int i = 0, j = 0;
  53. foreach(T v in arr) {
  54. arr2[i, j++] = v;
  55. if(j == s) {
  56. i++;
  57. j = 0;
  58. } // end of if()
  59. } // end of foreach()
  60. return arr2;
  61. } // end of to2DArray()
  62. /// <summary>
  63. /// Reads the data from a 2D array into the specified array
  64. /// </summary>
  65. /// <typeparam name="T"> The array element type </typeparam>
  66. /// <param name="arr"> The source 2D array </param>
  67. /// <param name="s"> The size of the 2D square array </param>
  68. /// <param name="sizes"> The size of the resulting array </param>
  69. /// <returns> The resulting array </returns>
  70. public static Array from2DArray<T>(T[,] arr, int s, int[] sizes) {
  71. switch(sizes.Length) {
  72. case 1:
  73. return from2DArrayTo1D<T>(arr, s, sizes);
  74. case 2:
  75. return arr;
  76. case 3:
  77. return from2DArrayTo3D<T>(arr, s, sizes);
  78. case 4:
  79. return from2DArrayTo4D<T>(arr, s, sizes);
  80. default:
  81. return from2DArrayToND<T>(arr, s, sizes);
  82. } // end of switch()
  83. } // end of from2DArray<T>()
  84. /// <summary>
  85. /// Reads the data from the 2D array into a 1D array
  86. /// </summary>
  87. /// <typeparam name="T"> The element type </typeparam>
  88. /// <param name="arr"> The 2D array </param>
  89. /// <param name="s"> The size of the 2D array </param>
  90. /// <param name="sizes"> The sizes of the 1D array </param>
  91. /// <returns> The resulting 1D array </returns>
  92. public static T[] from2DArrayTo1D<T>(T[,] arr, int s, int[] sizes) {
  93. int n = sizes[0];
  94. T[] arr2 = new T[n];
  95. int i = 0, j = 0;
  96. for(int p = 0; p < n; p++) {
  97. arr2[p] = arr[i, j++];
  98. if(j == s) {
  99. i++;
  100. j = 0;
  101. } // end of if()
  102. } // end of for()
  103. return arr2;
  104. } // end of from2DArrayTo1D()
  105. /// <summary>
  106. /// Converts a 2D array representation into a 3D array
  107. /// </summary>
  108. /// <typeparam name="T"> The array type </typeparam>
  109. /// <param name="arr"> The array to convert </param>
  110. /// <param name="s"> The size of the 2D array along one
  111. /// of the dimensions </param>
  112. /// <param name="sizes"> The sizes of the 3D array </param>
  113. /// <returns> The 3D array created </returns>
  114. public static T[, ,] from2DArrayTo3D<T>(T[,] arr, int s, int[] sizes) {
  115. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2];
  116. T[,,] arr2 = new T[n0, n1, n2];
  117. int i = 0, j = 0;
  118. for(int p0 = 0; p0 < n0; p0++)
  119. for(int p1 = 0; p1 < n1; p1++)
  120. for(int p2 = 0; p2 < n2; p2++) {
  121. arr2[p0, p1, p2] = arr[i, j++];
  122. if(j == s) {
  123. i++;
  124. j = 0;
  125. } // end of if()
  126. } // end of for()
  127. return arr2;
  128. } // end of from2DArrayTo3D<T>()
  129. /// <summary>
  130. /// Converts a 2D array representation into a 4D array
  131. /// </summary>
  132. /// <typeparam name="T"> The array type </typeparam>
  133. /// <param name="arr"> The array to convert </param>
  134. /// <param name="s"> The size of the 2D array along one
  135. /// of the dimensions </param>
  136. /// <param name="sizes"> The sizes of the 4D array </param>
  137. /// <returns> The 4D array created </returns>
  138. public static T[,, ,] from2DArrayTo4D<T>(T[,] arr, int s, int[] sizes) {
  139. int n0 = sizes[0], n1 = sizes[1], n2 = sizes[2], n3 = sizes[3];
  140. T[, , ,] arr2 = new T[n0, n1, n2, n3];
  141. int i = 0, j = 0;
  142. for(int p0 = 0; p0 < n0; p0++)
  143. for(int p1 = 0; p1 < n1; p1++)
  144. for(int p2 = 0; p2 < n2; p2++)
  145. for(int p3 = 0; p3 < n3; p3++) {
  146. arr2[p0, p1, p2, p3] = arr[i, j++];
  147. if(j == s) {
  148. i++;
  149. j = 0;
  150. } // end of if()
  151. } // end of for()
  152. return arr2;
  153. } // end of from2DArrayTo4D<T>()
  154. /// <summary>
  155. /// Reads the data from the 2D array into an ND array
  156. /// </summary>
  157. /// <typeparam name="T"> The element type </typeparam>
  158. /// <param name="arr"> The 2D array </param>
  159. /// <param name="s"> The size of the 2D array </param>
  160. /// <param name="sizes"> The sizes of the ND array </param>
  161. /// <returns> The resulting ND array </returns>
  162. public static Array from2DArrayToND<T>(T[,] arr, int s, int[] sizes) {
  163. int n = sizes[0];
  164. Array arr2 = Array.CreateInstance(typeof(T), sizes);
  165. int i = 0, j = 0;
  166. foreach(int[] p in pointIter(sizes)) {
  167. arr2.SetValue(arr[i, j++], p);
  168. if(j == s) {
  169. i++;
  170. j = 0;
  171. } // end of if()
  172. } // end of for()
  173. return arr2;
  174. } // end of from2DArrayToND()
  175. /// <summary>
  176. /// Checks whether the arrays have equal length and whether the predicate
  177. /// is valid for both of them
  178. /// </summary>
  179. /// <typeparam name="T1"> The type of the first array </typeparam>
  180. /// <typeparam name="T2"> The type of the second array </typeparam>
  181. /// <param name="arr1"> The first array </param>
  182. /// <param name="arr2"> The second array </param>
  183. /// <param name="prd"> The predicate to check </param>
  184. /// <returns> True iff either both <paramref name="arr1"/>
  185. /// and <paramref name="arr2"/> are null or both of them have equal length
  186. /// and for each pair of their respective elements the predicate
  187. /// <paramref name="prd"/> holds, i.e., returns true </returns>
  188. public static bool allTrue<T1, T2>(T1[] arr1, T2[] arr2, DoublePred<T1, T2> prd) {
  189. // check for null
  190. if(arr1 == null || arr2 == null) {
  191. return arr1 == null && arr2 == null;
  192. }
  193. if(prd == null)
  194. throw new ArgumentNullException();
  195. if(arr1.Length != arr2.Length)
  196. return false;
  197. int n = arr1.Length;
  198. for(int i = 0; i < n; i++)
  199. if(!prd(arr1[i], arr2[i]))
  200. return false;
  201. return true;
  202. }
  203. /// <summary>
  204. /// Concatenates the first array with the second array
  205. /// </summary>
  206. /// <typeparam name="T"> The type of the arrays being concatenated </typeparam>
  207. /// <param name="arr1"> The first array to be concatenated </param>
  208. /// <param name="arr2"> The second array to be concatenated </param>
  209. /// <returns> The result of concatenation </returns>
  210. public static T[] con<T>(T[] arr1, T[] arr2) {
  211. if(arr1 == null)
  212. return arr2;
  213. if(arr2 == null)
  214. return arr1;
  215. int l1 = arr1.Length, l2 = arr2.Length;
  216. int l = l1 + l2;
  217. T[] res = new T[l];
  218. int i = 0;
  219. for(; i < l1; i++)
  220. res[i] = arr1[i];
  221. for(; i < l; i++)
  222. res[i] = arr2[i - l1];
  223. return res;
  224. }
  225. /// <summary>
  226. /// Concatenates any number of arrays of the same type specified
  227. /// </summary>
  228. /// <typeparam name="T"> The element type of the arrays to concatenate </typeparam>
  229. /// <param name="arrs"> The arrays to concatenate </param>
  230. /// <returns> The result of concatenation </returns>
  231. public static T[] con<T>(params T[][] arrs) {
  232. if(arrs == null)
  233. return null;
  234. if(arrs.Length == 0)
  235. return new T[] { };
  236. if(Array.TrueForAll<T[]>(arrs, delegate(T[] a) { return a == null; }))
  237. return null;
  238. T[] res = arrs[0];
  239. for(int i = 1; i < arrs.Length; i++)
  240. res = con<T>(res, arrs[i]);
  241. return res;
  242. }
  243. /// <summary>
  244. /// Adds an element to the end of the array
  245. /// </summary>
  246. /// <typeparam name="T"> The type of the array element </typeparam>
  247. /// <param name="arr"> The array to concatenate </param>
  248. /// <param name="el"> The element to concatenate </param>
  249. /// <returns> The resulting array </returns>
  250. public static T[] con<T>(T[] arr, T el) {
  251. return con<T>(arr, new T[] { el });
  252. } // end of con<T>
  253. /// <summary>
  254. /// Adds an element to the beginning of the array
  255. /// </summary>
  256. /// <typeparam name="T"> The type of the array element </typeparam>
  257. /// <param name="el"> The element to concatenate </param>
  258. /// <param name="arr"> The array to concatenate </param>
  259. /// <returns> The resulting array </returns>
  260. public static T[] con<T>(T el, T[] arr) {
  261. return con<T>(new T[] { el }, arr);
  262. } // end of con<T>
  263. /// <summary>
  264. /// Indexes the array with an array of indices and returns the result of the
  265. /// indexing
  266. /// </summary>
  267. /// <typeparam name="T"> The type of the array to index </typeparam>
  268. /// <param name="arr"> The array to index </param>
  269. /// <param name="inds"> The indices of the elements to retrieve </param>
  270. /// <returns> The list of indices for indexing </returns>
  271. public static T[] index<T>(T[] arr, params int[] inds) {
  272. List<T> l = new List<T>();
  273. if(inds == null)
  274. return l.ToArray();
  275. if(arr == null) {
  276. if(inds == null || inds.Length == 0)
  277. return l.ToArray();
  278. throw new ArgumentNullException();
  279. }
  280. foreach(int i in inds)
  281. l.Add(arr[i]);
  282. return l.ToArray();
  283. }
  284. /// <summary>
  285. /// Gets the indices of the array given the single cumulative index.
  286. /// </summary>
  287. /// <param name="index"> The cumulative index of the array </param>
  288. /// <param name="cumSizes"> The cumulative sizes of the array. The
  289. /// last of it equals to 1, the next-to-last to cumSizes[cumSizes.Length - 1] *
  290. /// sizes[cumSizes.length - 1], etc. </param>
  291. /// <returns> The resulting set of indices </returns>
  292. public static int[] indices(int index, int[] cumSizes) {
  293. int n = cumSizes.Length;
  294. int[] inds = new int[n];
  295. int j = index;
  296. for(int i = 0; i < n; i++) {
  297. inds[i] = j / cumSizes[i];
  298. j %= cumSizes[i];
  299. }
  300. return inds;
  301. } // end of indices()
  302. /// <summary>
  303. /// Creates the array of cumulative sizes from the array of sizes
  304. /// </summary>
  305. /// <param name="sizes"> The array of sizes </param>
  306. /// <returns> The array of cumulative sizes </returns>
  307. /// <remarks> When it is created, it is assumed that the first index in
  308. /// the array changes the slowest </remarks>
  309. public static int[] cumSizes(int[] sizes) {
  310. int n = sizes.Length;
  311. int[] cs = new int[n];
  312. cs[n - 1] = 1;
  313. for(int i = n - 2; i >= 0; i--)
  314. cs[i] = cs[i + 1] * sizes[i + 1];
  315. return cs;
  316. }
  317. /// <summary>
  318. /// Creates a tail from an array starting from the specified element
  319. /// </summary>
  320. /// <typeparam name="T"> The type of the array element </typeparam>
  321. /// <param name="arr"> The array from which to create a tail </param>
  322. /// <param name="start"> The start element of the tail </param>
  323. /// <returns> The tail created </returns>
  324. public static T[] tail<T>(T[] arr, int start) {
  325. if(start <= 0)
  326. return arr;
  327. if(start >= arr.Length)
  328. throw new IndexOutOfRangeException();
  329. int nl = arr.Length - start;
  330. T[] res = new T[nl];
  331. for(int i = 0; i < nl; i++)
  332. res[i] = arr[start + i];
  333. return res;
  334. }
  335. /// <summary>
  336. /// Gets the array of sizes of the array.
  337. /// </summary>
  338. /// <param name="arr"> The array for which to get the sizes. </param>
  339. /// <returns> The array of sizes of the array, staring from the one
  340. /// along which changes the slowest (i.e., the first). Returns null for
  341. /// null arrays. </returns>
  342. public static int[] sizes(Array arr) {
  343. if(null == arr)
  344. return null;
  345. int n = arr.Rank;
  346. int[] sz = new int[n];
  347. for(int i = 0; i < n; i++)
  348. sz[i] = arr.GetLength(i);
  349. return sz;
  350. }
  351. /// <summary>
  352. /// Creates a 1D array of the specified type and of specified size with all
  353. /// elements equal to a specified value
  354. /// </summary>
  355. /// <typeparam name="T"> The type of the array to create </typeparam>
  356. /// <param name="val"> The value of the array element </param>
  357. /// <param name="size"> The length of the array to create </param>
  358. /// <returns> The array created </returns>
  359. public static T[] idarr<T>(T val, int size) {
  360. if(size < 0)
  361. throw new ArgumentOutOfRangeException();
  362. T[] arr = new T[size];
  363. for(int i = 0; i < arr.Length; i++)
  364. arr[i] = val;
  365. return arr;
  366. }
  367. /// <summary>
  368. /// Transforms two arrays of values into a single array of values
  369. /// </summary>
  370. /// <typeparam name="T1"> The type of the first array of values </typeparam>
  371. /// <typeparam name="T2"> The type of the second array of values </typeparam>
  372. /// <typeparam name="T3"> The type of the resulting array of values </typeparam>
  373. /// <param name="arr1"> The first array of values </param>
  374. /// <param name="arr2"> The second array of values </param>
  375. /// <param name="trs"> The transform to apply </param>
  376. /// <returns> The resulting array of values </returns>
  377. public static T3[] map2<T1, T2, T3>(T1[] arr1, T2[] arr2, Transform<T1, T2, T3>
  378. trs) {
  379. // check for nulls
  380. if(arr1 == null || arr2 == null) {
  381. if(arr1 == null && arr2 == null)
  382. return null;
  383. else
  384. throw new ArgumentNullException();
  385. }
  386. if(trs == null)
  387. throw new ArgumentNullException();
  388. if(arr1.Length != arr2.Length)
  389. throw new ArgumentException();
  390. int n = arr1.Length;
  391. T3[] res = new T3[n];
  392. for(int i = 0; i < n; i++)
  393. res[i] = trs(arr1[i], arr2[i]);
  394. return res;
  395. }
  396. /// <summary>
  397. /// Performs the reduction of the specified array by the specified function
  398. /// </summary>
  399. /// <typeparam name="T"> The type of the array to reduce </typeparam>
  400. /// <param name="arr"> The array being reduced </param>
  401. /// <param name="red"> The reducing function </param>
  402. /// <returns> The result of the reduciton </returns>
  403. public static T reduce<T>(T[] arr, Transform<T, T, T> red) {
  404. if(null == arr || null == red)
  405. throw new ArgumentNullException();
  406. if(arr.Length == 0)
  407. return default(T);
  408. if(arr.Length == 1)
  409. return arr[0];
  410. T res = arr[0];
  411. for(int i = 1; i < arr.Length; i++)
  412. res = red(res, arr[i]);
  413. return res;
  414. }
  415. /// <summary>
  416. /// Gets the head of the specified array
  417. /// </summary>
  418. /// <param name="arr"> The array from which to get the head </param>
  419. /// <param name="end"> The index of the last element to be included in
  420. /// the head array </param>
  421. /// <returns> The head of the array </returns>
  422. public static T[] head<T>(T[] arr, int end) {
  423. if(null == arr)
  424. return null;
  425. if(end < 0)
  426. throw new IndexOutOfRangeException();
  427. if(end >= arr.Length)
  428. return arr;
  429. T[] res = new T[end + 1];
  430. for(int i = 0; i <= end; i++)
  431. res[i] = arr[i];
  432. return res;
  433. }
  434. /// <summary>
  435. /// Accepts the list of arrays and returns
  436. /// their union
  437. /// </summary>
  438. /// <typeparam name="T"> The type of the arrays to unite </typeparam>
  439. /// <param name="arr"> The arrays to unite </param>
  440. /// <returns> The union of the arrays </returns>
  441. /// <remarks> The result does not have any repeating elements; that is,
  442. /// even if a single array is passed, it has its repeating elements
  443. /// removed </remarks>
  444. public static T[] union<T>(params T[][] arr) {
  445. if(null == arr || arr.Length == 0)
  446. return new T[] { };
  447. List<T> l = new List<T>();
  448. Set<T> s = new Set<T>();
  449. foreach(T[] a in arr) {
  450. if(null == a)
  451. continue;
  452. foreach(T el in a)
  453. if(!s.Contains(el)) {
  454. s.Add(el);
  455. l.Add(el);
  456. }
  457. }
  458. return l.ToArray();
  459. } // end of union()
  460. /// <summary>
  461. /// Accepts two arrays and returns their difference
  462. /// </summary>
  463. /// <typeparam name="T"> The type of the array </typeparam>
  464. /// <param name="arr1"> The first array </param>
  465. /// <param name="arr2"> The second array </param>
  466. /// <returns> The difference of the first and second arrays </returns>
  467. public static T[] diff<T>(T[] arr1, T[] arr2) {
  468. if(null == arr1 || null == arr2)
  469. throw new ArgumentNullException();
  470. List<T> l = new List<T>();
  471. Set<T> s = new Set<T>(arr1).Difference(new Set<T>(arr2));
  472. Set<T> s1 = new Set<T>(); // for there be no identical elements
  473. foreach(T el in arr1)
  474. if(s.Contains(el) && !s1.Contains(el)) {
  475. s1.Add(el);
  476. l.Add(el);
  477. }
  478. return l.ToArray();
  479. }
  480. /// <summary>
  481. /// Gets the array containing integer span of data between a and b
  482. /// </summary>
  483. /// <param name="a"> The start of the span </param>
  484. /// <param name="b"> The end of the span </param>
  485. /// <returns> The span created or null if none </returns>
  486. public static int[] span(int a, int b) {
  487. if(b < a) return null;
  488. int n = b - a + 1;
  489. int[] arr = new int[n];
  490. for(int i = a; i <= b; i++) arr[i - a] = i;
  491. return arr;
  492. } // end of span()
  493. /// <summary>
  494. /// Iterates over a rectangular set of integer points, starting from
  495. /// (0, ..., 0) and ending with (sizes[0]-1, ..., sizes[n-1]-1), with
  496. /// first index chaning the slowest. In case null or zero-length array
  497. /// is passed, returns a single zero-length array
  498. /// </summary>
  499. /// <param name="sizes"> The limits of the domain over which to
  500. /// iterate </param>
  501. /// <returns> The iterator over the point domain </returns>
  502. public static IEnumerable<int[]> pointIter(int[] sizes) {
  503. if(null == sizes || sizes.Length == 0) {
  504. yield return new int[0];
  505. yield break;
  506. } else {
  507. int n = sizes.Length;
  508. int[] vals = idarr<int>(-1, n);
  509. int ptr = 0;
  510. while(ptr != -1) {
  511. if(ptr == n) {
  512. yield return (int[])vals.Clone();
  513. ptr--;
  514. } else {
  515. vals[ptr]++;
  516. if(vals[ptr] == sizes[ptr]) {
  517. vals[ptr] = -1;
  518. ptr--;
  519. } else {
  520. ptr++;
  521. } // end of if()-else
  522. } // end of if()-else
  523. } // end of while()
  524. } // end of if()-else
  525. } // end of pointIter()
  526. /// <summary>
  527. /// Creates an array of <paramref name="size"/> elements, all of
  528. /// which are equal to <paramref name="val"/>, except for element
  529. /// with index <paramref name="pos"/>, which is equal to
  530. /// <paramref name="diffVal"/>
  531. /// </summary>
  532. /// <typeparam name="T"> The type of the element & array </typeparam>
  533. /// <param name="size"> The size of the resulting array </param>
  534. /// <param name="pos"> The position in the array which shall differ </param>
  535. /// <param name="val"> The value of the array element </param>
  536. /// <param name="diffVal"> The different value of the single element </param>
  537. /// <returns> The array created </returns>
  538. public static T[] singleDiff<T>(int size, int pos, T val, T diffVal) {
  539. T[] a = idarr<T>(val, size);
  540. a[pos] = diffVal;
  541. return a;
  542. } // end of singleDiff<T>()
  543. /// <summary>
  544. /// Evaluates the dot product of two integer arrays
  545. /// </summary>
  546. /// <param name="a1"> The first array </param>
  547. /// <param name="a2"> The second array </param>
  548. /// <returns> The dot product of two arrays </returns>
  549. public static int dot(int[] a1, int[] a2) {
  550. if(null == a1 || null == a2)
  551. throw new ArgumentNullException();
  552. int n = a1.Length;
  553. if(a2.Length != n)
  554. throw new ArgumentException();
  555. int r = 0;
  556. for(int i = 0; i < n; i++)
  557. r += a1[i] * a2[i];
  558. return r;
  559. } // end of dot()
  560. /// <summary>
  561. /// Assigns values of <paramref name="src"/> to <paramref name="tgt"/>,
  562. /// so that each element of <paramref name="src"/> is assigned to the
  563. /// <paramref name="inds"/> position with respective index of
  564. /// <paramref name="tgt"/>. If there are several candidates to the
  565. /// same position, any of them can be assigned.
  566. /// </summary>
  567. /// <typeparam name="T"> The type of the array </typeparam>
  568. /// <param name="tgt"> The target array </param>
  569. /// <param name="src"> The source array </param>
  570. /// <param name="inds"> The indices at which to assign </param>
  571. public static void arrass<T>(T[] tgt, T[] src, int[] inds) {
  572. int n = src.Length;
  573. if(inds.Length != n)
  574. throw new ArgumentException("Source and indices lengths do not match");
  575. for(int i = 0; i < n; i++) tgt[inds[i]] = src[i];
  576. } // end of arrass<T>
  577. /// <summary>
  578. /// Removes duplicates in the array
  579. /// </summary>
  580. /// <param name="arr"> The array from which to remove duplicates </param>
  581. /// <returns> The array with all duplicates removed </returns>
  582. public static T[] removeDups<T>(T[] arr) {
  583. List<T> l = new List<T>();
  584. Set<T> s = new Set<T>();
  585. foreach(T t in arr)
  586. if(!s.Contains(t)) {
  587. s.Add(t);
  588. l.Add(t);
  589. } // end of if()
  590. return l.ToArray();
  591. } // end of removeDups()
  592. /// <summary>
  593. /// Gets the indices of objects of <paramref name="arr2"/> with which
  594. /// they are present in <paramref name="arr1"/>
  595. /// </summary>
  596. /// <typeparam name="T"> The array type </typeparam>
  597. /// <param name="arr1"> The first array </param>
  598. /// <param name="arr2"> The second array </param>
  599. /// <returns> The array of indices </returns>
  600. public static int[] indicesOf<T>(T[] arr1, T[] arr2) {
  601. int n = arr2.Length;
  602. int[] inds = new int[n];
  603. for(int i = 0; i < n; i++)
  604. inds[i] = Array.IndexOf<T>(arr1, arr2[i]);
  605. return inds;
  606. } // end of indicesOf<T>
  607. } // end of class ArrOps
  608. }