PageRenderTime 68ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/CommitMonitor/src/com/fuelindustries/util/ArrayExtensions.as

http://breaktrycatchrepo.googlecode.com/
ActionScript | 313 lines | 182 code | 4 blank | 127 comment | 16 complexity | 66013537017c5568fe70af5b8b4839b2 MD5 | raw file
  1. package com.fuelindustries.util
  2. {
  3. /**
  4. * @author plemarquand
  5. */
  6. public class ArrayExtensions
  7. { /**
  8. * Runs an aggregator function on the supplied array and returns the result.
  9. * This is the equivalent to reduce in other languages, or aggregate in C#.
  10. * @param array An array of items to aggregate.
  11. * @param seed The seed object. The results of the aggregate are stored on this object.
  12. * If the object is a primitive type, a primitive is returned.
  13. * @param callback The aggregator function with the signature <code>function(seed : *, item : *):*</code>.
  14. * @return The aggregated value.
  15. *
  16. * <code>
  17. * var arr2 : Array = ["a","b","C","d","e"];
  18. * var seed : String = ArrayExtensions.aggregate(arr2, "", function(n : *,newN : *):*
  19. * {
  20. * return n + newN;
  21. * });
  22. * trace("Aggregated Result: " + seed) // traces: abCde.
  23. * </code>
  24. */
  25. public static function aggregate(array : Array, seed : *, callback : Function) : *
  26. {
  27. var isPrimitive : Boolean = ObjectUtil.isSimple( seed );
  28. simpleForEach( array, function(item : *):void
  29. {
  30. if(isPrimitive)
  31. {
  32. seed = callback( seed, item );
  33. }
  34. else
  35. {
  36. callback( seed, item );
  37. }
  38. } );
  39. return seed;
  40. }
  41. /**
  42. * Transforms the supplied array to be unique.
  43. * @param arr An array with potentially duplicate elements in it.
  44. * @return The transformed array. Operations are made on the original array.
  45. */
  46. public static function distinct(arr : Array) : Array
  47. {
  48. return arr.filter( function (item : *, index : int, array : Array):Boolean
  49. {
  50. return array.indexOf( item, index + 1 ) == -1;
  51. } );
  52. }
  53. /**
  54. * Returns a boolean indicating if all of the elements in the array meet
  55. * the conditions defined in the predicate.
  56. * @param arr An array of elements to check against the predicate.
  57. * @param callback A predicate function with the signature <code>function(item : *, index : int, array : Array):Boolean</code>
  58. * @return Whether all the elements in the array satisfy the predicate or not.
  59. */
  60. public static function equalAll(arr : Array, callback : Function) : Boolean
  61. {
  62. return !arr.some( function(item : *, index : int, array : Array):Boolean
  63. {
  64. return !callback( item, index, array );
  65. } );
  66. }
  67. /**
  68. * Produces the set difference of the first array against the second.
  69. * @param arr1 An array of elements to perform the except on.
  70. * @param arr2 An array of elements to remove from the first set.
  71. * @return All elements contained within the first array that are not present in the second.
  72. */
  73. public static function except(arr : Array, except : Array) : Array
  74. {
  75. return arr.filter( function(item : *, ...args):Boolean
  76. {
  77. return except.indexOf( item ) == -1;
  78. } );
  79. }
  80. /**
  81. * Returns the first element in an array that matches the given condition.
  82. * @param arr An array of elements to search with the predicate function
  83. * @param callback A predicate function with the signature <code>function(item : *, index : int, array : Array):Boolean</code>
  84. * @return The first matching element based on the criteria set in the predicate function.
  85. */
  86. public static function first(arr : Array, callback : Function) : *
  87. {
  88. var savedIndex : int = -1;
  89. arr.some( function(item : *, index : int, array : Array):Boolean
  90. {
  91. if(callback( item, index, array ))
  92. {
  93. savedIndex = index;
  94. return true;
  95. }
  96. return false;
  97. } );
  98. return (savedIndex == -1) ? (null) : (arr[savedIndex]);
  99. }
  100. /**
  101. * Returns the first element in an array whose property matches the supplied
  102. * value. For example, if you're looking for user.id:
  103. * ArrayExtensions.firstByProperty(userArray, 'id', 12345);
  104. * @param arr An array to search.
  105. * @param property A property name that is contained on all objects in the array.
  106. * @param searchValue A value to search for.
  107. */
  108. public static function firstByProperty(arr : Array, property : String, searchValue : *) : *
  109. {
  110. return first( arr, function(item : *, ...args):Boolean
  111. {
  112. return item[property] == searchValue;
  113. } );
  114. }
  115. /**
  116. * Finds the common set of elements between two Arrays.
  117. * @param arr1 An array of elements.
  118. * @param arr2 Another array of elements.
  119. * @return A new array containing the common set of elements between the arrays.
  120. */
  121. public static function intersect(arr1 : Array, arr2 : Array) : Array
  122. {
  123. var larger : Array;
  124. var smaller : Array;
  125. if(arr1.length > arr2.length)
  126. {
  127. larger = arr1;
  128. smaller = arr2;
  129. }
  130. else
  131. {
  132. larger = arr2;
  133. smaller = arr1;
  134. }
  135. return larger.filter( function(item : *, ...args):Boolean
  136. {
  137. return smaller.indexOf( item ) != -1;
  138. } );
  139. }
  140. /**
  141. * Returns all elements of a supplied type.
  142. * @param arr An array of elements.
  143. * @param type The type of elements to search for in the array.
  144. * @return A new array containing all the elements of the supplied type from the suppled array.
  145. */
  146. public static function ofType(arr : Array, type : Class) : Array
  147. {
  148. return arr.filter( function(item : *, ...args) : Boolean
  149. {
  150. return item is type;
  151. } );
  152. }
  153. /**
  154. * Returns the first n elements of an array. If n is greater than the length
  155. * of the array, then the entire array is returned.
  156. */
  157. public static function take(arr : Array, n : int) : Array
  158. {
  159. return arr.slice( 0, n );
  160. }
  161. /**
  162. * Runs a predicate function on each element in the array and if the predicate returns
  163. * true, then a callback function is run on the item.
  164. * @param array An array of items to run the predicate/callback on.
  165. * @param conditional A predicate function with the signature <code>function(item : *, index : int, array : Array):Boolean</code>
  166. * @param callback A callback function with the signature <code>function(item : *, index : int, array : Array):void</code>
  167. */
  168. public static function predicate(array : Array, conditional : Function, callback : Function) : void
  169. {
  170. array.forEach( function (item : *, index : int, array : Array):void
  171. {
  172. if(conditional( item, index, array ))
  173. {
  174. callback( item, index, array );
  175. }
  176. } );
  177. }
  178. /**
  179. * Returns a union between two two arrays excluding duplicate elements.
  180. * @param arr1 The first array to join.
  181. * @param arr2 The second array to join.
  182. * @return An array that has been joined together excluding unique elements.
  183. */
  184. public static function union(arr1 : Array, arr2 : Array) : Array
  185. {
  186. return distinct( arr1.concat( arr2 ) );
  187. }
  188. /**
  189. * Creates a new array and removes duplicate items from it.
  190. * @param An array to remove duplicates from
  191. * @return A unique array.
  192. */
  193. public static function unique(arr : Array) : Array
  194. {
  195. var newArr : Array = arr.concat();
  196. for( var i : int=0; i < newArr.length; ++i )
  197. {
  198. var ty : Object = newArr[ i ];
  199. for( var j : int = i + 1; j < newArr.length; ++j )
  200. {
  201. while( ty == newArr[ j ] )
  202. {
  203. newArr.splice( j, 1 );
  204. }
  205. }
  206. }
  207. return arr;
  208. }
  209. /**
  210. * Returns a random element from an array. If the array is empty
  211. * the function returns undefined.
  212. * @param arr An array from which to select a random element.
  213. * @return A random element from the array.
  214. */
  215. public static function randomElement(arr : Array) : *
  216. {
  217. if ( arr.length == 0 )
  218. {
  219. return undefined;
  220. }
  221. return arr[ Math.floor( Math.random( ) * arr.length ) ];
  222. }
  223. /**
  224. * Creates a new copy of the supplied array and randomizes its elements.
  225. * @param arr An array to randomize.
  226. * @return A new randomized array.
  227. */
  228. public static function randomize(arr : Array) : Array
  229. {
  230. var len : Number = arr.length;
  231. var shuffled : Array = arr.concat( );
  232. var rnd : Number;
  233. var i : Number; // using a number here is *considerably* faster than an integer.
  234. var item : *;
  235. while (i < len)
  236. {
  237. item = shuffled[i];
  238. shuffled[i] = shuffled[rnd = i + Math.random( ) * (len - i)];
  239. shuffled[rnd] = item;
  240. i++;
  241. }
  242. return shuffled;
  243. }
  244. /**
  245. * Returns an array populated with a range of numbers. The range is inclusive,
  246. * meaning that the start and end numbers will be included in the range. The
  247. * start and end values can be any integer numbers in an order.
  248. * @param start The start of the range.
  249. * @param end The end point of the range.
  250. * @return An array contianing a linear array of elements from start to start to end.
  251. */
  252. public static function range(start : int, end : int) : Array
  253. {
  254. var higher : int = (start > end) ? (start) : (end);
  255. var lower : int = (start < end) ? (start) : (end);
  256. var direction : int = (end > start) ? (1) : (-1);
  257. var range : int = higher - lower;
  258. var ctr : int = 0;
  259. var arr : Array = [];
  260. var len : int = range;
  261. for ( var i : Number = 0; i <= len ; i++ )
  262. {
  263. arr.push( start + ctr );
  264. ctr += direction;
  265. }
  266. return arr;
  267. }
  268. /**
  269. * Creates a copy of the original array and reverses it in place.
  270. * @param arr An array to reverse.
  271. * @return A new reversed array.
  272. */
  273. public static function reverse(arr : Array) : Array
  274. {
  275. return arr.concat( ).reverse( );
  276. }
  277. /**
  278. * A simple wrapper for Array.forEach that calls your callback function
  279. * using only the item in the array as a parameter. For example, regular forEach
  280. * requires a callback with the signature
  281. * <code>function(item : *, index : int, array : Array):void;</code>
  282. * however using this function the method signature is:
  283. * <code>function(item : *):void;</code>
  284. * @param items An array of items to be passed to the callback one by one.
  285. * @param callback The callback to be run.
  286. */
  287. public static function simpleForEach(items : Array, callback : Function) : void
  288. {
  289. items.forEach( function(item : *, ...args):void
  290. {
  291. callback( item );
  292. } );
  293. }
  294. /**
  295. * Executes a callback on every item in the array. The function must
  296. * exist on all items in the supplied array.
  297. * @param array An array of items to execute a callback on.
  298. * @param callback The string name of a callback to execute on all functions.
  299. * @param callbackArgs Arguments to supply to the callback.
  300. */
  301. public static function executeCallbackOnArray(array : Array, callback : String, ...callbackArgs) : void
  302. {
  303. simpleForEach( array, function(item : *) : void
  304. {
  305. item[callback].apply( item, callbackArgs );
  306. } );
  307. }
  308. }
  309. }