array.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojo._base.array"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojo._base.array"] = true;
  8. dojo.provide("dojo._base.array");
  9. dojo.require("dojo._base.lang");
  10. (function(){
  11. var _getParts = function(arr, obj, cb){
  12. return [
  13. (typeof arr == "string") ? arr.split("") : arr,
  14. obj || dojo.global,
  15. // FIXME: cache the anonymous functions we create here?
  16. (typeof cb == "string") ? new Function("item", "index", "array", cb) : cb
  17. ];
  18. };
  19. var everyOrSome = function(/*Boolean*/every, /*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  20. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  21. for(var i=0,l=arr.length; i<l; ++i){
  22. var result = !!_p[2].call(_p[1], arr[i], i, arr);
  23. if(every ^ result){
  24. return result; // Boolean
  25. }
  26. }
  27. return every; // Boolean
  28. };
  29. dojo.mixin(dojo, {
  30. indexOf: function( /*Array*/ array,
  31. /*Object*/ value,
  32. /*Integer?*/ fromIndex,
  33. /*Boolean?*/ findLast){
  34. // summary:
  35. // locates the first index of the provided value in the
  36. // passed array. If the value is not found, -1 is returned.
  37. // description:
  38. // This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
  39. // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
  40. // 1.6's indexOf skips the holes in the sparse array.
  41. // For details on this method, see:
  42. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
  43. var step = 1, end = array.length || 0, i = 0;
  44. if(findLast){
  45. i = end - 1;
  46. step = end = -1;
  47. }
  48. if(fromIndex != undefined){ i = fromIndex; }
  49. if((findLast && i > end) || i < end){
  50. for(; i != end; i += step){
  51. if(array[i] == value){ return i; }
  52. }
  53. }
  54. return -1; // Number
  55. },
  56. lastIndexOf: function(/*Array*/array, /*Object*/value, /*Integer?*/fromIndex){
  57. // summary:
  58. // locates the last index of the provided value in the passed
  59. // array. If the value is not found, -1 is returned.
  60. // description:
  61. // This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
  62. // run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
  63. // 1.6's lastIndexOf skips the holes in the sparse array.
  64. // For details on this method, see:
  65. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
  66. return dojo.indexOf(array, value, fromIndex, true); // Number
  67. },
  68. forEach: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  69. // summary:
  70. // for every item in arr, callback is invoked. Return values are ignored.
  71. // If you want to break out of the loop, consider using dojo.every() or dojo.some().
  72. // forEach does not allow breaking out of the loop over the items in arr.
  73. // arr:
  74. // the array to iterate over. If a string, operates on individual characters.
  75. // callback:
  76. // a function is invoked with three arguments: item, index, and array
  77. // thisObject:
  78. // may be used to scope the call to callback
  79. // description:
  80. // This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
  81. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  82. // the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
  83. // For more details, see:
  84. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
  85. // example:
  86. // | // log out all members of the array:
  87. // | dojo.forEach(
  88. // | [ "thinger", "blah", "howdy", 10 ],
  89. // | function(item){
  90. // | console.log(item);
  91. // | }
  92. // | );
  93. // example:
  94. // | // log out the members and their indexes
  95. // | dojo.forEach(
  96. // | [ "thinger", "blah", "howdy", 10 ],
  97. // | function(item, idx, arr){
  98. // | console.log(item, "at index:", idx);
  99. // | }
  100. // | );
  101. // example:
  102. // | // use a scoped object member as the callback
  103. // |
  104. // | var obj = {
  105. // | prefix: "logged via obj.callback:",
  106. // | callback: function(item){
  107. // | console.log(this.prefix, item);
  108. // | }
  109. // | };
  110. // |
  111. // | // specifying the scope function executes the callback in that scope
  112. // | dojo.forEach(
  113. // | [ "thinger", "blah", "howdy", 10 ],
  114. // | obj.callback,
  115. // | obj
  116. // | );
  117. // |
  118. // | // alternately, we can accomplish the same thing with dojo.hitch()
  119. // | dojo.forEach(
  120. // | [ "thinger", "blah", "howdy", 10 ],
  121. // | dojo.hitch(obj, "callback")
  122. // | );
  123. // match the behavior of the built-in forEach WRT empty arrs
  124. if(!arr || !arr.length){ return; }
  125. // FIXME: there are several ways of handilng thisObject. Is
  126. // dojo.global always the default context?
  127. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  128. for(var i=0,l=arr.length; i<l; ++i){
  129. _p[2].call(_p[1], arr[i], i, arr);
  130. }
  131. },
  132. every: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  133. // summary:
  134. // Determines whether or not every item in arr satisfies the
  135. // condition implemented by callback.
  136. // arr:
  137. // the array to iterate on. If a string, operates on individual characters.
  138. // callback:
  139. // a function is invoked with three arguments: item, index,
  140. // and array and returns true if the condition is met.
  141. // thisObject:
  142. // may be used to scope the call to callback
  143. // description:
  144. // This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
  145. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  146. // the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
  147. // For more details, see:
  148. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
  149. // example:
  150. // | // returns false
  151. // | dojo.every([1, 2, 3, 4], function(item){ return item>1; });
  152. // example:
  153. // | // returns true
  154. // | dojo.every([1, 2, 3, 4], function(item){ return item>0; });
  155. return everyOrSome(true, arr, callback, thisObject); // Boolean
  156. },
  157. some: function(/*Array|String*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  158. // summary:
  159. // Determines whether or not any item in arr satisfies the
  160. // condition implemented by callback.
  161. // arr:
  162. // the array to iterate over. If a string, operates on individual characters.
  163. // callback:
  164. // a function is invoked with three arguments: item, index,
  165. // and array and returns true if the condition is met.
  166. // thisObject:
  167. // may be used to scope the call to callback
  168. // description:
  169. // This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
  170. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  171. // the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
  172. // For more details, see:
  173. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
  174. // example:
  175. // | // is true
  176. // | dojo.some([1, 2, 3, 4], function(item){ return item>1; });
  177. // example:
  178. // | // is false
  179. // | dojo.some([1, 2, 3, 4], function(item){ return item<1; });
  180. return everyOrSome(false, arr, callback, thisObject); // Boolean
  181. },
  182. map: function(/*Array|String*/arr, /*Function|String*/callback, /*Function?*/thisObject){
  183. // summary:
  184. // applies callback to each element of arr and returns
  185. // an Array with the results
  186. // arr:
  187. // the array to iterate on. If a string, operates on
  188. // individual characters.
  189. // callback:
  190. // a function is invoked with three arguments, (item, index,
  191. // array), and returns a value
  192. // thisObject:
  193. // may be used to scope the call to callback
  194. // description:
  195. // This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
  196. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  197. // the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
  198. // For more details, see:
  199. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  200. // example:
  201. // | // returns [2, 3, 4, 5]
  202. // | dojo.map([1, 2, 3, 4], function(item){ return item+1 });
  203. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  204. var outArr = (arguments[3] ? (new arguments[3]()) : []);
  205. for(var i=0,l=arr.length; i<l; ++i){
  206. outArr.push(_p[2].call(_p[1], arr[i], i, arr));
  207. }
  208. return outArr; // Array
  209. },
  210. filter: function(/*Array*/arr, /*Function|String*/callback, /*Object?*/thisObject){
  211. // summary:
  212. // Returns a new Array with those items from arr that match the
  213. // condition implemented by callback.
  214. // arr:
  215. // the array to iterate over.
  216. // callback:
  217. // a function that is invoked with three arguments (item,
  218. // index, array). The return of this function is expected to
  219. // be a boolean which determines whether the passed-in item
  220. // will be included in the returned array.
  221. // thisObject:
  222. // may be used to scope the call to callback
  223. // description:
  224. // This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
  225. // run over sparse arrays, this implemenation passes the "holes" in the sparse array to
  226. // the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
  227. // For more details, see:
  228. // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  229. // example:
  230. // | // returns [2, 3, 4]
  231. // | dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
  232. var _p = _getParts(arr, thisObject, callback); arr = _p[0];
  233. var outArr = [];
  234. for(var i=0,l=arr.length; i<l; ++i){
  235. if(_p[2].call(_p[1], arr[i], i, arr)){
  236. outArr.push(arr[i]);
  237. }
  238. }
  239. return outArr; // Array
  240. }
  241. });
  242. })();
  243. /*
  244. */
  245. }