Posted By

MichaelJWilliams on 09/20/08


Tagged

array tagging tags set collection intersection additems


Versions (?)

Who likes this?

4 people have marked this snippet as a favorite

THEPWN3R
zimmen
thastylos
tspitzr


AS3 Collection Class


 / Published in: ActionScript 3
 

URL: http://gamedev.michaeljameswilliams.com/2008/09/20/actionscript-3-collection-class

Check my blog for full details. This class adds extra functionality to the Array class by allowing methods like .intersection(anotherCollection), .union(anotherCollection), and .subCollection(property, valueToMatch). Useful for implementing a tagging system.

  1. package {
  2. /**
  3. * Collection Class
  4. * Version 1.0, 2008-09-20
  5. * Created by Michael James Williams
  6. * http://www.michaeljameswilliams.com
  7. */
  8. public class Collection extends Object {
  9.  
  10. public var _collection:Array;
  11.  
  12. /**
  13. * Creates a new collection populated with the specified values
  14. * @param ... values
  15. */
  16. public function Collection(... values) {
  17. _collection = new Array();
  18. addItems(values);
  19. }
  20.  
  21. /**
  22. * Adds the specified items to the collection
  23. * @param ... items
  24. */
  25. public function addItems(... items):void {
  26. for each (var item in items) {
  27. if (item is Array) {
  28. for each (var subItem in item) {
  29. addItems(subItem);
  30. }
  31. } else if (item is Collection) {
  32. for each (subItem in item.itemList) {
  33. addItems(subItem);
  34. }
  35. } else {
  36. if (!contains(item)) {
  37. _collection.push(item);
  38. }
  39. }
  40. }
  41. }
  42.  
  43. /**
  44. * Removes all of the specified items from the collection
  45. * @param ... items
  46. */
  47. public function removeItems(... items):void {
  48. for each (var item in items) {
  49. if (item is Array) {
  50. for each (var subItem in item) {
  51. removeItems(subItem);
  52. }
  53. } else if (item is Collection) {
  54. for each (subItem in item.itemList) {
  55. removeItems(subItem);
  56. }
  57. } else if (contains(item)) {
  58. _collection.splice(_collection.indexOf(item), 1);
  59. }
  60. }
  61. }
  62.  
  63. /**
  64. * Returns true iff collection contains (or is) specified item
  65. * @param item
  66. * @return
  67. */
  68. public function contains(item):Boolean {
  69. if ((item is Array) || (item is Collection)) {
  70. return containsAll(item);
  71. } else {
  72. if ((_collection.indexOf(item) > -1) || (this === item)) {
  73. return true;
  74. } else {
  75. return false;
  76. }
  77. }
  78. }
  79.  
  80. /**
  81. * Returns true iff collection contains all specified items (including subitems of an array or collection)
  82. * @param ... items
  83. * @return
  84. */
  85. public function containsAll(... items):Boolean {
  86. var all:Boolean = true;
  87. for each (var item in items) {
  88. if (item is Array) {
  89. for each (var subItem in item) {
  90. if (!_collection.containsAll(subItem)) { all = false; }
  91. }
  92. } else if (item is Collection) {
  93. for each (subItem in item.itemList) {
  94. if (!_collection.containsAll(subItem)) { all = false; }
  95. }
  96. } else {
  97. if (!_collection.contains(item)) { all = false; }
  98. }
  99. }
  100. return all;
  101. }
  102.  
  103. /**
  104. * Returns true iff collection contains any of the specified items (including subitems of an array or collection)
  105. * @param ... items
  106. * @return
  107. */
  108. public function containsAny(... items):Boolean {
  109. var any:Boolean = false;
  110. for each (var item in items) {
  111. if (item is Array) {
  112. for each (var subItem in item) {
  113. if (!_collection.containsAny(subItem)) {
  114. any = true;
  115. break;
  116. }
  117. }
  118. } else if (item is Collection) {
  119. for each (subItem in item.itemList) {
  120. if (!_collection.containsAny(subItem)) {
  121. any = true;
  122. break;
  123. }
  124. }
  125. } else {
  126. if (!_collection.contains(item)) {
  127. any = true;
  128. break;
  129. }
  130. }
  131. }
  132. return any;
  133. }
  134.  
  135. /**
  136. * Executes a test function on each item in the collection and constructs a new collection of all items that return true.
  137. * @param callback
  138. * @param thisObject
  139. * @return
  140. */
  141. public function filter(callback:Function, thisObject:* = null):Collection {
  142. var filtered:Collection = new Collection();
  143. filtered.addItems(_collection.filter(callback, thisObject));
  144. return filtered;
  145. }
  146.  
  147. /**
  148. * Executes a function on each item in the collection.
  149. * @param callback
  150. * @param thisObject
  151. */
  152. public function forEach(callback:Function, thisObject:* = null):void {
  153. _collection.forEach(callback, thisObject);
  154. }
  155.  
  156. /**
  157. * Converts the elements in a collection to strings, inserts the specified separator between the elements, concatenates them, and returns the resulting string.
  158. * @param sep
  159. * @return
  160. */
  161. public function join(sep:*):String {
  162. return _collection.join(sep);
  163. }
  164.  
  165. /**
  166. * Executes a function on each item in an collection, and constructs a new collection of items corresponding to the results of the function on each item in the original collection.
  167. * @param callback
  168. * @param thisObject
  169. * @return
  170. */
  171. public function map(callback:Function, thisObject:* = null):Collection {
  172. var mappedArray:Array = _collection.map(callback, thisObject);
  173. var mappedCollection:Collection = new Collection();
  174. for each (var item in mappedArray) {
  175. mappedCollection.addItems(item);
  176. }
  177. return mappedCollection;
  178. }
  179.  
  180. /**
  181. * Executes a test function on each item in the collection until an item is reached that returns true. Use this method to determine whether any items in a collection meet a criterion, such as having a value less than a particular number.
  182. * @param callback
  183. * @param thisObject
  184. * @return
  185. */
  186. public function some(callback:Function, thisObject:* = null):Boolean {
  187. return _collection.some(callback, thisObject);
  188. }
  189.  
  190. /**
  191. * Executes a test function on each item in the collection until an item is reached that returns false for the specified function. You use this method to determine whether all items in a collection meet a criterion, such as having values less than a particular number.
  192. * @param callback
  193. * @param thisObject
  194. * @return
  195. */
  196. public function every(callback:Function, thisObject:* = null):Boolean {
  197. return _collection.every(callback, thisObject);
  198. }
  199.  
  200. /**
  201. * Returns a collection made up of items in this collection for which item.property==value
  202. * @param property
  203. * @param value
  204. * @return
  205. */
  206. public function subCollection(property:String, value:*):Collection {
  207. ///Ideally this would accept a method name and a ...params and check to see if item.method(...params)==true
  208. var subCollection:Collection = new Collection();
  209. for each (var item in _collection) {
  210. try {
  211. if (item[property]==value) {
  212. subCollection.addItems(item);
  213. }
  214. } catch (err) {
  215. //this is likely to be very very error prone if the programmer isn't careful so we'll just break out of the loop
  216. break;
  217. }
  218. }
  219. return subCollection;
  220. }
  221.  
  222. /**
  223. * Returns a collection made up of all items that are in both this collection and the specified collection
  224. * @param coll
  225. * @return
  226. */
  227. public function intersection(coll:Collection):Collection {
  228. var intersectColl:Collection=new Collection();
  229. for each (var item in coll.itemList) {
  230. if (this.contains(item)) {
  231. intersectColl.addItems(item);
  232. }
  233. }
  234. return intersectColl;
  235. }
  236.  
  237. /**
  238. * Returns the intersection of this collection with an arbitrary number of other collections
  239. * @param ... colls
  240. * @return
  241. */
  242. public function intersectMany(... colls):Collection {
  243. var intersectColl:Collection = new Collection();
  244. intersectColl.addItems(_collection);
  245. for each (var subItem in colls) {
  246. if (subItem is Collection) {
  247. intersectColl = intersectColl.intersection(subItem);
  248. }
  249. }
  250. return intersectColl;
  251. }
  252.  
  253. /**
  254. * Returns a collection made up of all items that are in either this collection or the specified collection (or both)
  255. * @param coll
  256. * @return
  257. */
  258. public function union(coll:Collection):Collection {
  259. var unionColl:Collection = new Collection();
  260. unionColl.addItems(itemList, coll);
  261. return unionColl;
  262. }
  263.  
  264. /**
  265. * Returns the union of this collection with an arbitrary number of other collections
  266. * @param ... colls
  267. * @return
  268. */
  269. public function unionMany(... colls):Collection {
  270. var unionColl:Collection = new Collection();
  271. unionColl.addItems(_collection);
  272. for each (var subItem in colls) {
  273. if (subItem is Collection) {
  274. unionColl = unionColl.union(subItem);
  275. }
  276. }
  277. return unionColl;
  278. }
  279.  
  280. /**
  281. * Returns the relative complement of the specified collection in this collection
  282. * A.relComp(B) := A\B
  283. * @param coll
  284. * @return
  285. */
  286. public function relComp(coll):Collection {
  287. ///Returns the relative complement of the specified collection in this collection
  288. ///A.relComp(B) := A\B
  289. ///i.e. returns a collection containing items that are in this collection but not in the specified collection
  290. var rcColl:Collection = new Collection();
  291. rcColl.addItems(_collection);
  292. rcColl.removeItems(coll);
  293. return rcColl;
  294. }
  295.  
  296. /**
  297. * Returns the relative complement of the union of the specified collections in this collection
  298. * @param ... colls
  299. * @return
  300. */
  301. public function relCompMany(... colls):Collection {
  302. var rcColl:Collection = new Collection();
  303. rcColl.addItems(_collection);
  304. for each (var subItem in colls) {
  305. if (subItem is Collection) {
  306. rcColl.removeItems(subItem);
  307. }
  308. }
  309. return rcColl;
  310. }
  311.  
  312. /**
  313. * Returns the number of items in the collection
  314. */
  315. public function get numItems():uint {
  316. return _collection.length;
  317. }
  318.  
  319. /**
  320. * Exposes the underlying array; use this only for e.g. for-each loops
  321. */
  322. public function get itemList():Array {
  323. return _collection;
  324. }
  325. }
  326. }

Report this snippet  

You need to login to post a comment.