/PGK.Extensions/ArrayExtension.cs

# · C# · 259 lines · 95 code · 20 blank · 144 comment · 32 complexity · 8eb96f53baa3ec7edbcb00fd93f2bcec MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. /// <summary>
  4. /// Extension methods for the array data type
  5. /// </summary>
  6. public static class ArrayExtension
  7. {
  8. ///<summary>
  9. /// Check if the array is null or empty
  10. ///</summary>
  11. ///<param name = "source"></param>
  12. ///<returns></returns>
  13. public static bool IsNullOrEmpty(this Array source)
  14. {
  15. return source == null || source.Length == 0;
  16. }
  17. ///<summary>
  18. /// Check if the index is within the array
  19. ///</summary>
  20. ///<param name = "source"></param>
  21. ///<param name = "index"></param>
  22. ///<returns></returns>
  23. /// <remarks>
  24. /// Contributed by Michael T, http://about.me/MichaelTran
  25. /// </remarks>
  26. public static bool WithinIndex(this Array source, int index)
  27. {
  28. return source != null && index >= 0 && index < source.Length;
  29. }
  30. ///<summary>
  31. /// Check if the index is within the array
  32. ///</summary>
  33. ///<param name = "source"></param>
  34. ///<param name = "index"></param>
  35. ///<param name="dimension"></param>
  36. ///<returns></returns>
  37. /// <remarks>
  38. /// Contributed by Michael T, http://about.me/MichaelTran
  39. /// </remarks>
  40. public static bool WithinIndex(this Array source, int index, int dimension = 0)
  41. {
  42. return source != null && index >= source.GetLowerBound(dimension) && index <= source.GetUpperBound(dimension);
  43. }
  44. /// <summary>
  45. /// Combine two arrays into one.
  46. /// </summary>
  47. /// <typeparam name="T">Type of Array</typeparam>
  48. /// <param name="combineWith">Base array in which arrayToCombine will add.</param>
  49. /// <param name="arrayToCombine">Array to combine with Base array.</param>
  50. /// <returns></returns>
  51. /// <example>
  52. /// <code>
  53. /// int[] arrayOne = new[] { 1, 2, 3, 4 };
  54. /// int[] arrayTwo = new[] { 5, 6, 7, 8 };
  55. /// Array combinedArray = arrayOne.CombineArray<int>(arrayTwo);
  56. /// </code>
  57. /// </example>
  58. /// <remarks>
  59. /// Contributed by Mohammad Rahman, http://mohammad-rahman.blogspot.com/
  60. /// </remarks>
  61. public static T[] CombineArray<T>(this T[] combineWith, T[] arrayToCombine)
  62. {
  63. if (combineWith != default(T[]) && arrayToCombine != default(T[]))
  64. {
  65. int initialSize = combineWith.Length;
  66. Array.Resize<T>(ref combineWith, initialSize + arrayToCombine.Length);
  67. Array.Copy(arrayToCombine, arrayToCombine.GetLowerBound(0), combineWith, initialSize, arrayToCombine.Length);
  68. }
  69. return combineWith;
  70. }
  71. /// <summary>
  72. /// To clear the contents of the array.
  73. /// </summary>
  74. /// <param name="clear"> The array to clear</param>
  75. /// <returns>Cleared array</returns>
  76. /// <example>
  77. /// <code>
  78. /// Array array = Array.CreateInstance(typeof(string), 2);
  79. /// array.SetValue("One", 0); array.SetValue("Two", 1);
  80. /// Array arrayToClear = array.ClearAll();
  81. /// </code>
  82. /// </example>
  83. /// <remarks>
  84. /// Contributed by Mohammad Rahman, http://mohammad-rahman.blogspot.com/
  85. /// </remarks>
  86. public static Array ClearAll(this Array clear)
  87. {
  88. if (clear != null)
  89. Array.Clear(clear, 0, clear.Length);
  90. return clear;
  91. }
  92. /// <summary>
  93. /// To clear the contents of the array.
  94. /// </summary>
  95. /// <typeparam name="T">The type of array</typeparam>
  96. /// <param name="clear"> The array to clear</param>
  97. /// <returns>Cleared array</returns>
  98. /// <example>
  99. /// <code>
  100. /// int[] result = new[] { 1, 2, 3, 4 }.ClearAll<int>();
  101. /// </code>
  102. /// </example>
  103. /// <remarks>
  104. /// Contributed by Mohammad Rahman, http://mohammad-rahman.blogspot.com/
  105. /// </remarks>
  106. public static T[] ClearAll<T>(this T[] arrayToClear)
  107. {
  108. if (arrayToClear != null)
  109. for (int i = arrayToClear.GetLowerBound(0); i <= arrayToClear.GetUpperBound(0); ++i)
  110. arrayToClear[i] = default(T);
  111. return arrayToClear;
  112. }
  113. /// <summary>
  114. /// To clear a specific item in the array.
  115. /// </summary>
  116. /// <param name="arrayToClear">The array in where to clean the item.</param>
  117. /// <param name="at">Which element to clear.</param>
  118. /// <returns></returns>
  119. /// <example>
  120. /// <code>
  121. /// Array array = Array.CreateInstance(typeof(string), 2);
  122. /// array.SetValue("One", 0); array.SetValue("Two", 1);
  123. /// Array result = array.ClearAt(2);
  124. /// </code>
  125. /// </example>
  126. /// <remarks>
  127. /// Contributed by Mohammad Rahman, http://mohammad-rahman.blogspot.com/
  128. /// </remarks>
  129. public static Array ClearAt(this Array arrayToClear, int at)
  130. {
  131. if (arrayToClear != null)
  132. {
  133. int arrayIndex = at.GetArrayIndex();
  134. if (arrayIndex.IsIndexInArray(arrayToClear))
  135. Array.Clear(arrayToClear, arrayIndex, 1);
  136. }
  137. return arrayToClear;
  138. }
  139. /// <summary>
  140. /// To clear a specific item in the array.
  141. /// </summary>
  142. /// <typeparam name="T">The type of array</typeparam>
  143. /// <param name="arrayToClear">Array to clear.</param>
  144. /// <param name="at">Which element to clear.</param>
  145. /// <returns></returns>
  146. /// <example>
  147. /// <code>
  148. /// string[] clearString = new[] { "A" }.ClearAt<string>(0);
  149. /// </code>
  150. /// </example>
  151. /// <remarks>
  152. /// Contributed by Mohammad Rahman, http://mohammad-rahman.blogspot.com/
  153. /// </remarks>
  154. public static T[] ClearAt<T>(this T[] arrayToClear, int at)
  155. {
  156. if (arrayToClear != null)
  157. {
  158. int arrayIndex = at.GetArrayIndex();
  159. if (arrayIndex.IsIndexInArray(arrayToClear))
  160. arrayToClear[arrayIndex] = default(T);
  161. }
  162. return arrayToClear;
  163. }
  164. /// <summary>
  165. /// Tests if the array is empty.
  166. /// </summary>
  167. /// <param name="array">The array to test.</param>
  168. /// <returns>True if the array is empty.</returns>
  169. public static bool IsEmpty(this Array array)
  170. {
  171. array.ExceptionIfNullOrEmpty(
  172. "The array cannot be null.",
  173. "array");
  174. return array.Length == 0;
  175. }
  176. #region BlockCopy
  177. /// <summary>
  178. /// Returns a block of items from an array
  179. /// </summary>
  180. /// <typeparam name="T"></typeparam>
  181. /// <param name="array"></param>
  182. /// <param name="index"></param>
  183. /// <param name="length"></param>
  184. /// <returns></returns>
  185. /// <remarks>Contributed by Chris Gessler</remarks>
  186. public static T[] BlockCopy<T>(this T[] array, int index, int length)
  187. {
  188. return BlockCopy(array, index, length, false);
  189. }
  190. /// <summary>
  191. /// Returns a block of items from an array
  192. /// </summary>
  193. /// <typeparam name="T"></typeparam>
  194. /// <param name="array"></param>
  195. /// <param name="index"></param>
  196. /// <param name="length"></param>
  197. /// <param name="padToLength"></param>
  198. /// <returns></returns>
  199. /// <remarks>
  200. /// Test results prove that Array.Copy is many times faster than Skip/Take and LINQ
  201. /// Item count: 1,000,000
  202. /// Array.Copy: 15 ms
  203. /// Skip/Take: 42,464 ms - 42.5 seconds
  204. /// LINQ: 881 ms
  205. ///
  206. /// Contributed by Chris Gessler</remarks>
  207. public static T[] BlockCopy<T>(this T[] array, int index, int length, bool padToLength)
  208. {
  209. if (array == null) throw new NullReferenceException();
  210. int n = length;
  211. T[] b = null;
  212. if (array.Length < index + length)
  213. {
  214. n = array.Length - index;
  215. if (padToLength)
  216. {
  217. b = new T[length];
  218. }
  219. }
  220. if (b == null) b = new T[n];
  221. Array.Copy(array, index, b, 0, n);
  222. return b;
  223. }
  224. /// <summary>
  225. /// Allows enumeration over an Array in blocks
  226. /// </summary>
  227. /// <typeparam name="T"></typeparam>
  228. /// <param name="array"></param>
  229. /// <param name="count"></param>
  230. /// <param name="padToLength"></param>
  231. /// <returns></returns>
  232. /// <remarks>Contributed by Chris Gessler</remarks>
  233. public static IEnumerable<T[]> BlockCopy<T>(this T[] array, int count, bool padToLength = false)
  234. {
  235. for (int i = 0; i < array.Length; i += count)
  236. yield return array.BlockCopy(i, count, padToLength);
  237. }
  238. #endregion
  239. }