PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/gallery-iterable-extras/js/iterable-extras.js

https://github.com/soulge/yui3-gallery
JavaScript | 297 lines | 137 code | 28 blank | 132 comment | 16 complexity | 920a008b7e56e558025936ef20d42ba4 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
  1. "use strict";
  2. /**
  3. * @module gallery-iterable-extras
  4. */
  5. /**********************************************************************
  6. * <p>Functional programming support for iterable classes. The class must
  7. * implement the `iterator` and `newInstance` methods.</p>
  8. *
  9. * <p>For most methods, the iterator only needs to implement `next` and
  10. * `atEnd`. Backwards iterators like `reduceRight` require `prev` and
  11. * `atBeginning`.</p>
  12. *
  13. * <p>Iterable classes must mix these functions: `Y.mix(SomeClass,
  14. * Y.Iterable, false, null, 4);` Passing false as the third argument
  15. * allows your class to provide optimized implementations of individual
  16. * functions.</p>
  17. *
  18. * @main gallery-iterable-extras
  19. * @class Iterable
  20. */
  21. Y.Iterable =
  22. {
  23. /**
  24. * Executes the supplied function on each item in the list. The
  25. * function receives the value, the index, and the list itself as
  26. * parameters (in that order).
  27. *
  28. * @method each
  29. * @param f {Function} the function to execute on each item
  30. * @param c {Object} optional context object
  31. */
  32. each: function(f, c)
  33. {
  34. var iter = this.iterator(), i = 0;
  35. while (!iter.atEnd())
  36. {
  37. f.call(c, iter.next(), i, this);
  38. i++;
  39. }
  40. },
  41. /**
  42. * Executes the supplied function on each item in the list. Iteration
  43. * stops if the supplied function does not return a truthy value. The
  44. * function receives the value, the index, and the list itself as
  45. * parameters (in that order).
  46. *
  47. * @method every
  48. * @param f {Function} the function to execute on each item
  49. * @param c {Object} optional context object
  50. * @return {Boolean} true if every item in the array returns true from the supplied function, false otherwise
  51. */
  52. every: function(f, c)
  53. {
  54. var iter = this.iterator(), i = 0;
  55. while (!iter.atEnd())
  56. {
  57. if (!f.call(c, iter.next(), i, this))
  58. {
  59. return false;
  60. }
  61. i++;
  62. }
  63. return true;
  64. },
  65. /**
  66. * Executes the supplied function on each item in the list. Returns a
  67. * new list containing the items for which the supplied function
  68. * returned a truthy value. The function receives the value, the
  69. * index, and the object itself as parameters (in that order).
  70. *
  71. * @method filter
  72. * @param f {Function} the function to execute on each item
  73. * @param c {Object} optional context object
  74. * @return {Object} list of items for which the supplied function returned a truthy value (empty if it never returned a truthy value)
  75. */
  76. filter: function(f, c)
  77. {
  78. var result = this.newInstance();
  79. var iter = this.iterator(), i = 0;
  80. while (!iter.atEnd())
  81. {
  82. var item = iter.next();
  83. if (f.call(c, item, i, this))
  84. {
  85. result.append(item);
  86. }
  87. i++;
  88. }
  89. return result;
  90. },
  91. /**
  92. * Executes the supplied function on each item in the list, searching
  93. * for the first item that matches the supplied function. The function
  94. * receives the value, the index, and the object itself as parameters
  95. * (in that order).
  96. *
  97. * @method find
  98. * @param f {Function} the function to execute on each item
  99. * @param c {Object} optional context object
  100. * @return {Mixed} the first item for which the supplied function returns true, or null if it never returns true
  101. */
  102. find: function(f, c)
  103. {
  104. var iter = this.iterator(), i = 0;
  105. while (!iter.atEnd())
  106. {
  107. var item = iter.next();
  108. if (f.call(c, item, i, this))
  109. {
  110. return item;
  111. }
  112. i++;
  113. }
  114. return null;
  115. },
  116. /**
  117. * Executes the supplied function on each item in the list and returns
  118. * a new list with the results. The function receives the value, the
  119. * index, and the object itself as parameters (in that order).
  120. *
  121. * @method map
  122. * @param f {String} the function to invoke
  123. * @param c {Object} optional context object
  124. * @return {Object} list of all return values
  125. */
  126. map: function(f, c)
  127. {
  128. var result = this.newInstance();
  129. var iter = this.iterator(), i = 0;
  130. while (!iter.atEnd())
  131. {
  132. result.append(f.call(c, iter.next(), i, this));
  133. i++;
  134. }
  135. return result;
  136. },
  137. /**
  138. * Partitions an list into two new list, one with the items for which
  139. * the supplied function returns true, and one with the items for which
  140. * the function returns false. The function receives the value, the
  141. * index, and the object itself as parameters (in that order).
  142. *
  143. * @method partition
  144. * @param f {Function} the function to execute on each item
  145. * @param c {Object} optional context object
  146. * @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).
  147. */
  148. partition: function(f, c)
  149. {
  150. var result =
  151. {
  152. matches: this.newInstance(),
  153. rejects: this.newInstance()
  154. };
  155. var iter = this.iterator(), i = 0;
  156. while (!iter.atEnd())
  157. {
  158. var item = iter.next();
  159. result[ f.call(c, item, i, this) ? 'matches' : 'rejects' ].append(item);
  160. i++;
  161. }
  162. return result;
  163. },
  164. /**
  165. * Executes the supplied function on each item in the list, folding the
  166. * list into a single value. The function receives the value returned
  167. * by the previous iteration (or the initial value if this is the first
  168. * iteration), the value being iterated, the index, and the list itself
  169. * as parameters (in that order). The function must return the updated
  170. * value.
  171. *
  172. * @method reduce
  173. * @param init {Mixed} the initial value
  174. * @param f {String} the function to invoke
  175. * @param c {Object} optional context object
  176. * @return {Mixed} final result from iteratively applying the given function to each item in the list
  177. */
  178. reduce: function(init, f, c)
  179. {
  180. var result = init;
  181. var iter = this.iterator(), i = 0;
  182. while (!iter.atEnd())
  183. {
  184. result = f.call(c, result, iter.next(), i, this);
  185. i++;
  186. }
  187. return result;
  188. },
  189. /**
  190. * Executes the supplied function on each item in the list, starting
  191. * from the end and folding the list into a single value. The function
  192. * receives the value returned by the previous iteration (or the
  193. * initial value if this is the first iteration), the value being
  194. * iterated, the index, and the list itself as parameters (in that
  195. * order). The function must return the updated value.
  196. *
  197. * @method reduceRight
  198. * @param init {Mixed} the initial value
  199. * @param f {String} the function to invoke
  200. * @param c {Object} optional context object
  201. * @return {Mixed} final result from iteratively applying the given function to each item in the list
  202. */
  203. reduceRight: function(init, f, c)
  204. {
  205. var result = init;
  206. var iter = this.iterator(), i = 0;
  207. while (!iter.atEnd())
  208. {
  209. iter.next();
  210. i++;
  211. }
  212. while (!iter.atBeginning())
  213. {
  214. i--;
  215. result = f.call(c, result, iter.prev(), i, this);
  216. }
  217. return result;
  218. },
  219. /**
  220. * Executes the supplied function on each item in the list. Returns a
  221. * new list containing the items for which the supplied function
  222. * returned a falsey value. The function receives the value, the
  223. * index, and the object itself as parameters (in that order).
  224. *
  225. * @method reject
  226. * @param f {Function} the function to execute on each item
  227. * @param c {Object} optional context object
  228. * @return {Object} array or object of items for which the supplied function returned a falsey value (empty if it never returned a falsey value)
  229. */
  230. reject: function(f, c)
  231. {
  232. var result = this.newInstance();
  233. var iter = this.iterator(), i = 0;
  234. while (!iter.atEnd())
  235. {
  236. var item = iter.next();
  237. if (!f.call(c, item, i, this))
  238. {
  239. result.append(item);
  240. }
  241. i++;
  242. }
  243. return result;
  244. },
  245. /**
  246. * Executes the supplied function on each item in the list. Iteration
  247. * stops if the supplied function returns a truthy value. The function
  248. * receives the value, the index, and the list itself as parameters
  249. * (in that order).
  250. *
  251. * @method some
  252. * @param f {Function} the function to execute on each item
  253. * @param c {Object} optional context object
  254. * @return {Boolean} true if the function returns a truthy value on any of the items in the array, false otherwise
  255. */
  256. some: function(f, c)
  257. {
  258. var iter = this.iterator(), i = 0;
  259. while (!iter.atEnd())
  260. {
  261. if (f.call(c, iter.next(), i, this))
  262. {
  263. return true;
  264. }
  265. i++;
  266. }
  267. return false;
  268. }
  269. };