PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/build/gallery-iterable-extras/gallery-iterable-extras.js

https://github.com/soulge/yui3-gallery
JavaScript | 389 lines | 179 code | 40 blank | 170 comment | 18 complexity | ed683241bc4e268c3a3c7ef7bc4a38c9 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. YUI.add('gallery-iterable-extras', function(Y) {
  2. "use strict";
  3. /**
  4. * @module gallery-iterable-extras
  5. */
  6. /**********************************************************************
  7. * <p>Functional programming support for iterable classes. The class must
  8. * implement the `iterator` and `newInstance` methods.</p>
  9. *
  10. * <p>For most methods, the iterator only needs to implement `next` and
  11. * `atEnd`. Backwards iterators like `reduceRight` require `prev` and
  12. * `atBeginning`.</p>
  13. *
  14. * <p>Iterable classes must mix these functions: `Y.mix(SomeClass,
  15. * Y.Iterable, false, null, 4);` Passing false as the third argument
  16. * allows your class to provide optimized implementations of individual
  17. * functions.</p>
  18. *
  19. * @main gallery-iterable-extras
  20. * @class Iterable
  21. */
  22. Y.Iterable =
  23. {
  24. /**
  25. * Executes the supplied function on each item in the list. The
  26. * function receives the value, the index, and the list itself as
  27. * parameters (in that order).
  28. *
  29. * @method each
  30. * @param f {Function} the function to execute on each item
  31. * @param c {Object} optional context object
  32. */
  33. each: function(f, c)
  34. {
  35. var iter = this.iterator(), i = 0;
  36. while (!iter.atEnd())
  37. {
  38. f.call(c, iter.next(), i, this);
  39. i++;
  40. }
  41. },
  42. /**
  43. * Executes the supplied function on each item in the list. Iteration
  44. * stops if the supplied function does not return a truthy value. The
  45. * function receives the value, the index, and the list itself as
  46. * parameters (in that order).
  47. *
  48. * @method every
  49. * @param f {Function} the function to execute on each item
  50. * @param c {Object} optional context object
  51. * @return {Boolean} true if every item in the array returns true from the supplied function, false otherwise
  52. */
  53. every: function(f, c)
  54. {
  55. var iter = this.iterator(), i = 0;
  56. while (!iter.atEnd())
  57. {
  58. if (!f.call(c, iter.next(), i, this))
  59. {
  60. return false;
  61. }
  62. i++;
  63. }
  64. return true;
  65. },
  66. /**
  67. * Executes the supplied function on each item in the list. Returns a
  68. * new list containing the items for which the supplied function
  69. * returned a truthy value. The function receives the value, the
  70. * index, and the object itself as parameters (in that order).
  71. *
  72. * @method filter
  73. * @param f {Function} the function to execute on each item
  74. * @param c {Object} optional context object
  75. * @return {Object} list of items for which the supplied function returned a truthy value (empty if it never returned a truthy value)
  76. */
  77. filter: function(f, c)
  78. {
  79. var result = this.newInstance();
  80. var iter = this.iterator(), i = 0;
  81. while (!iter.atEnd())
  82. {
  83. var item = iter.next();
  84. if (f.call(c, item, i, this))
  85. {
  86. result.append(item);
  87. }
  88. i++;
  89. }
  90. return result;
  91. },
  92. /**
  93. * Executes the supplied function on each item in the list, searching
  94. * for the first item that matches the supplied function. The function
  95. * receives the value, the index, and the object itself as parameters
  96. * (in that order).
  97. *
  98. * @method find
  99. * @param f {Function} the function to execute on each item
  100. * @param c {Object} optional context object
  101. * @return {Mixed} the first item for which the supplied function returns true, or null if it never returns true
  102. */
  103. find: function(f, c)
  104. {
  105. var iter = this.iterator(), i = 0;
  106. while (!iter.atEnd())
  107. {
  108. var item = iter.next();
  109. if (f.call(c, item, i, this))
  110. {
  111. return item;
  112. }
  113. i++;
  114. }
  115. return null;
  116. },
  117. /**
  118. * Executes the supplied function on each item in the list and returns
  119. * a new list with the results. The function receives the value, the
  120. * index, and the object itself as parameters (in that order).
  121. *
  122. * @method map
  123. * @param f {String} the function to invoke
  124. * @param c {Object} optional context object
  125. * @return {Object} list of all return values
  126. */
  127. map: function(f, c)
  128. {
  129. var result = this.newInstance();
  130. var iter = this.iterator(), i = 0;
  131. while (!iter.atEnd())
  132. {
  133. result.append(f.call(c, iter.next(), i, this));
  134. i++;
  135. }
  136. return result;
  137. },
  138. /**
  139. * Partitions an list into two new list, one with the items for which
  140. * the supplied function returns true, and one with the items for which
  141. * the function returns false. The function receives the value, the
  142. * index, and the object itself as parameters (in that order).
  143. *
  144. * @method partition
  145. * @param f {Function} the function to execute on each item
  146. * @param c {Object} optional context object
  147. * @return {Object} object with two properties: matches and rejects. Each is a list containing the items that were selected or rejected by the test function (or an empty object if none).
  148. */
  149. partition: function(f, c)
  150. {
  151. var result =
  152. {
  153. matches: this.newInstance(),
  154. rejects: this.newInstance()
  155. };
  156. var iter = this.iterator(), i = 0;
  157. while (!iter.atEnd())
  158. {
  159. var item = iter.next();
  160. result[ f.call(c, item, i, this) ? 'matches' : 'rejects' ].append(item);
  161. i++;
  162. }
  163. return result;
  164. },
  165. /**
  166. * Executes the supplied function on each item in the list, folding the
  167. * list into a single value. The function receives the value returned
  168. * by the previous iteration (or the initial value if this is the first
  169. * iteration), the value being iterated, the index, and the list itself
  170. * as parameters (in that order). The function must return the updated
  171. * value.
  172. *
  173. * @method reduce
  174. * @param init {Mixed} the initial value
  175. * @param f {String} the function to invoke
  176. * @param c {Object} optional context object
  177. * @return {Mixed} final result from iteratively applying the given function to each item in the list
  178. */
  179. reduce: function(init, f, c)
  180. {
  181. var result = init;
  182. var iter = this.iterator(), i = 0;
  183. while (!iter.atEnd())
  184. {
  185. result = f.call(c, result, iter.next(), i, this);
  186. i++;
  187. }
  188. return result;
  189. },
  190. /**
  191. * Executes the supplied function on each item in the list, starting
  192. * from the end and folding the list into a single value. The function
  193. * receives the value returned by the previous iteration (or the
  194. * initial value if this is the first iteration), the value being
  195. * iterated, the index, and the list itself as parameters (in that
  196. * order). The function must return the updated value.
  197. *
  198. * @method reduceRight
  199. * @param init {Mixed} the initial value
  200. * @param f {String} the function to invoke
  201. * @param c {Object} optional context object
  202. * @return {Mixed} final result from iteratively applying the given function to each item in the list
  203. */
  204. reduceRight: function(init, f, c)
  205. {
  206. var result = init;
  207. var iter = this.iterator(), i = 0;
  208. while (!iter.atEnd())
  209. {
  210. iter.next();
  211. i++;
  212. }
  213. while (!iter.atBeginning())
  214. {
  215. i--;
  216. result = f.call(c, result, iter.prev(), i, this);
  217. }
  218. return result;
  219. },
  220. /**
  221. * Executes the supplied function on each item in the list. Returns a
  222. * new list containing the items for which the supplied function
  223. * returned a falsey value. The function receives the value, the
  224. * index, and the object itself as parameters (in that order).
  225. *
  226. * @method reject
  227. * @param f {Function} the function to execute on each item
  228. * @param c {Object} optional context object
  229. * @return {Object} array or object of items for which the supplied function returned a falsey value (empty if it never returned a falsey value)
  230. */
  231. reject: function(f, c)
  232. {
  233. var result = this.newInstance();
  234. var iter = this.iterator(), i = 0;
  235. while (!iter.atEnd())
  236. {
  237. var item = iter.next();
  238. if (!f.call(c, item, i, this))
  239. {
  240. result.append(item);
  241. }
  242. i++;
  243. }
  244. return result;
  245. },
  246. /**
  247. * Executes the supplied function on each item in the list. Iteration
  248. * stops if the supplied function returns a truthy value. The function
  249. * receives the value, the index, and the list itself as parameters
  250. * (in that order).
  251. *
  252. * @method some
  253. * @param f {Function} the function to execute on each item
  254. * @param c {Object} optional context object
  255. * @return {Boolean} true if the function returns a truthy value on any of the items in the array, false otherwise
  256. */
  257. some: function(f, c)
  258. {
  259. var iter = this.iterator(), i = 0;
  260. while (!iter.atEnd())
  261. {
  262. if (f.call(c, iter.next(), i, this))
  263. {
  264. return true;
  265. }
  266. i++;
  267. }
  268. return false;
  269. }
  270. };
  271. /**
  272. * @module gallery-iterable-extras
  273. */
  274. /**********************************************************************
  275. * Iterator for an array. Useful for any class that manages an array and
  276. * wants to mix in `Y.Iterable`. Safe, but not stable, when the array is
  277. * modified during iteration.
  278. *
  279. * @class ArrayIterator
  280. * @method constructor
  281. * @param list {Array}
  282. */
  283. function ArrayIterator(
  284. /* array */ list)
  285. {
  286. this._list = list;
  287. this.moveToBeginning();
  288. }
  289. ArrayIterator.prototype =
  290. {
  291. /**
  292. * @method atBeginning
  293. * @return {Boolean} true if at the beginning
  294. */
  295. atBeginning: function()
  296. {
  297. return (this._next <= 0);
  298. },
  299. /**
  300. * @method atEnd
  301. * @return {Boolean} true if at the end
  302. */
  303. atEnd: function()
  304. {
  305. return (this._next >= this._list.length);
  306. },
  307. /**
  308. * Move to the beginning of the list.
  309. *
  310. * @method moveToBeginning
  311. */
  312. moveToBeginning: function()
  313. {
  314. this._next = 0;
  315. },
  316. /**
  317. * Move to the end of the list.
  318. *
  319. * @method moveToEnd
  320. */
  321. moveToEnd: function()
  322. {
  323. this._next = this._list.length;
  324. },
  325. /**
  326. * @method next
  327. * @return {Mixed} next value in the list or undefined if at the end
  328. */
  329. next: function()
  330. {
  331. if (this._next < this._list.length)
  332. {
  333. return this._list[ this._next++ ];
  334. }
  335. },
  336. /**
  337. * @method prev
  338. * @return {Mixed} previous value in the list or undefined if at the beginning
  339. */
  340. prev: function()
  341. {
  342. if (this._next > 0)
  343. {
  344. return this._list[ --this._next ];
  345. }
  346. }
  347. };
  348. Y.ArrayIterator = ArrayIterator;
  349. }, 'gallery-2012.05.23-19-56' ,{optional:['gallery-funcprog']});