Array2.html 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-Array'>/**
  19. </span> * @class Ext.Array
  20. * @singleton
  21. * @author Jacky Nguyen &lt;jacky@sencha.com&gt;
  22. * @docauthor Jacky Nguyen &lt;jacky@sencha.com&gt;
  23. *
  24. * A set of useful static methods to deal with arrays; provide missing methods for older browsers.
  25. */
  26. (function() {
  27. var arrayPrototype = Array.prototype,
  28. slice = arrayPrototype.slice,
  29. supportsSplice = (function () {
  30. var array = [],
  31. lengthBefore,
  32. j = 20;
  33. if (!array.splice) {
  34. return false;
  35. }
  36. // This detects a bug in IE8 splice method:
  37. // see http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/6e946d03-e09f-4b22-a4dd-cd5e276bf05a/
  38. while (j--) {
  39. array.push(&quot;A&quot;);
  40. }
  41. array.splice(15, 0, &quot;F&quot;, &quot;F&quot;, &quot;F&quot;, &quot;F&quot;, &quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;,&quot;F&quot;);
  42. lengthBefore = array.length; //41
  43. array.splice(13, 0, &quot;XXX&quot;); // add one element
  44. if (lengthBefore+1 != array.length) {
  45. return false;
  46. }
  47. // end IE8 bug
  48. return true;
  49. }()),
  50. supportsForEach = 'forEach' in arrayPrototype,
  51. supportsMap = 'map' in arrayPrototype,
  52. supportsIndexOf = 'indexOf' in arrayPrototype,
  53. supportsEvery = 'every' in arrayPrototype,
  54. supportsSome = 'some' in arrayPrototype,
  55. supportsFilter = 'filter' in arrayPrototype,
  56. supportsSort = (function() {
  57. var a = [1,2,3,4,5].sort(function(){ return 0; });
  58. return a[0] === 1 &amp;&amp; a[1] === 2 &amp;&amp; a[2] === 3 &amp;&amp; a[3] === 4 &amp;&amp; a[4] === 5;
  59. }()),
  60. supportsSliceOnNodeList = true,
  61. ExtArray,
  62. erase,
  63. replace,
  64. splice;
  65. try {
  66. // IE 6 - 8 will throw an error when using Array.prototype.slice on NodeList
  67. if (typeof document !== 'undefined') {
  68. slice.call(document.getElementsByTagName('body'));
  69. }
  70. } catch (e) {
  71. supportsSliceOnNodeList = false;
  72. }
  73. function fixArrayIndex (array, index) {
  74. return (index &lt; 0) ? Math.max(0, array.length + index)
  75. : Math.min(array.length, index);
  76. }
  77. /*
  78. Does the same work as splice, but with a slightly more convenient signature. The splice
  79. method has bugs in IE8, so this is the implementation we use on that platform.
  80. The rippling of items in the array can be tricky. Consider two use cases:
  81. index=2
  82. removeCount=2
  83. /=====\
  84. +---+---+---+---+---+---+---+---+
  85. | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
  86. +---+---+---+---+---+---+---+---+
  87. / \/ \/ \/ \
  88. / /\ /\ /\ \
  89. / / \/ \/ \ +--------------------------+
  90. / / /\ /\ +--------------------------+ \
  91. / / / \/ +--------------------------+ \ \
  92. / / / /+--------------------------+ \ \ \
  93. / / / / \ \ \ \
  94. v v v v v v v v
  95. +---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+
  96. | 0 | 1 | 4 | 5 | 6 | 7 | | 0 | 1 | a | b | c | 4 | 5 | 6 | 7 |
  97. +---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+
  98. A B \=========/
  99. insert=[a,b,c]
  100. In case A, it is obvious that copying of [4,5,6,7] must be left-to-right so
  101. that we don't end up with [0,1,6,7,6,7]. In case B, we have the opposite; we
  102. must go right-to-left or else we would end up with [0,1,a,b,c,4,4,4,4].
  103. */
  104. function replaceSim (array, index, removeCount, insert) {
  105. var add = insert ? insert.length : 0,
  106. length = array.length,
  107. pos = fixArrayIndex(array, index),
  108. remove,
  109. tailOldPos,
  110. tailNewPos,
  111. tailCount,
  112. lengthAfterRemove,
  113. i;
  114. // we try to use Array.push when we can for efficiency...
  115. if (pos === length) {
  116. if (add) {
  117. array.push.apply(array, insert);
  118. }
  119. } else {
  120. remove = Math.min(removeCount, length - pos);
  121. tailOldPos = pos + remove;
  122. tailNewPos = tailOldPos + add - remove;
  123. tailCount = length - tailOldPos;
  124. lengthAfterRemove = length - remove;
  125. if (tailNewPos &lt; tailOldPos) { // case A
  126. for (i = 0; i &lt; tailCount; ++i) {
  127. array[tailNewPos+i] = array[tailOldPos+i];
  128. }
  129. } else if (tailNewPos &gt; tailOldPos) { // case B
  130. for (i = tailCount; i--; ) {
  131. array[tailNewPos+i] = array[tailOldPos+i];
  132. }
  133. } // else, add == remove (nothing to do)
  134. if (add &amp;&amp; pos === lengthAfterRemove) {
  135. array.length = lengthAfterRemove; // truncate array
  136. array.push.apply(array, insert);
  137. } else {
  138. array.length = lengthAfterRemove + add; // reserves space
  139. for (i = 0; i &lt; add; ++i) {
  140. array[pos+i] = insert[i];
  141. }
  142. }
  143. }
  144. return array;
  145. }
  146. function replaceNative (array, index, removeCount, insert) {
  147. if (insert &amp;&amp; insert.length) {
  148. if (index &lt; array.length) {
  149. array.splice.apply(array, [index, removeCount].concat(insert));
  150. } else {
  151. array.push.apply(array, insert);
  152. }
  153. } else {
  154. array.splice(index, removeCount);
  155. }
  156. return array;
  157. }
  158. function eraseSim (array, index, removeCount) {
  159. return replaceSim(array, index, removeCount);
  160. }
  161. function eraseNative (array, index, removeCount) {
  162. array.splice(index, removeCount);
  163. return array;
  164. }
  165. function spliceSim (array, index, removeCount) {
  166. var pos = fixArrayIndex(array, index),
  167. removed = array.slice(index, fixArrayIndex(array, pos+removeCount));
  168. if (arguments.length &lt; 4) {
  169. replaceSim(array, pos, removeCount);
  170. } else {
  171. replaceSim(array, pos, removeCount, slice.call(arguments, 3));
  172. }
  173. return removed;
  174. }
  175. function spliceNative (array) {
  176. return array.splice.apply(array, slice.call(arguments, 1));
  177. }
  178. erase = supportsSplice ? eraseNative : eraseSim;
  179. replace = supportsSplice ? replaceNative : replaceSim;
  180. splice = supportsSplice ? spliceNative : spliceSim;
  181. // NOTE: from here on, use erase, replace or splice (not native methods)...
  182. ExtArray = Ext.Array = {
  183. <span id='Ext-Array-method-each'> /**
  184. </span> * Iterates an array or an iterable value and invoke the given callback function for each item.
  185. *
  186. * var countries = ['Vietnam', 'Singapore', 'United States', 'Russia'];
  187. *
  188. * Ext.Array.each(countries, function(name, index, countriesItSelf) {
  189. * console.log(name);
  190. * });
  191. *
  192. * var sum = function() {
  193. * var sum = 0;
  194. *
  195. * Ext.Array.each(arguments, function(value) {
  196. * sum += value;
  197. * });
  198. *
  199. * return sum;
  200. * };
  201. *
  202. * sum(1, 2, 3); // returns 6
  203. *
  204. * The iteration can be stopped by returning false in the function callback.
  205. *
  206. * Ext.Array.each(countries, function(name, index, countriesItSelf) {
  207. * if (name === 'Singapore') {
  208. * return false; // break here
  209. * }
  210. * });
  211. *
  212. * {@link Ext#each Ext.each} is alias for {@link Ext.Array#each Ext.Array.each}
  213. *
  214. * @param {Array/NodeList/Object} iterable The value to be iterated. If this
  215. * argument is not iterable, the callback function is called once.
  216. * @param {Function} fn The callback function. If it returns false, the iteration stops and this method returns
  217. * the current `index`.
  218. * @param {Object} fn.item The item at the current `index` in the passed `array`
  219. * @param {Number} fn.index The current `index` within the `array`
  220. * @param {Array} fn.allItems The `array` itself which was passed as the first argument
  221. * @param {Boolean} fn.return Return false to stop iteration.
  222. * @param {Object} scope (Optional) The scope (`this` reference) in which the specified function is executed.
  223. * @param {Boolean} reverse (Optional) Reverse the iteration order (loop from the end to the beginning)
  224. * Defaults false
  225. * @return {Boolean} See description for the `fn` parameter.
  226. */
  227. each: function(array, fn, scope, reverse) {
  228. array = ExtArray.from(array);
  229. var i,
  230. ln = array.length;
  231. if (reverse !== true) {
  232. for (i = 0; i &lt; ln; i++) {
  233. if (fn.call(scope || array[i], array[i], i, array) === false) {
  234. return i;
  235. }
  236. }
  237. }
  238. else {
  239. for (i = ln - 1; i &gt; -1; i--) {
  240. if (fn.call(scope || array[i], array[i], i, array) === false) {
  241. return i;
  242. }
  243. }
  244. }
  245. return true;
  246. },
  247. <span id='Ext-Array-method-forEach'> /**
  248. </span> * Iterates an array and invoke the given callback function for each item. Note that this will simply
  249. * delegate to the native Array.prototype.forEach method if supported. It doesn't support stopping the
  250. * iteration by returning false in the callback function like {@link Ext.Array#each}. However, performance
  251. * could be much better in modern browsers comparing with {@link Ext.Array#each}
  252. *
  253. * @param {Array} array The array to iterate
  254. * @param {Function} fn The callback function.
  255. * @param {Object} fn.item The item at the current `index` in the passed `array`
  256. * @param {Number} fn.index The current `index` within the `array`
  257. * @param {Array} fn.allItems The `array` itself which was passed as the first argument
  258. * @param {Object} scope (Optional) The execution scope (`this`) in which the specified function is executed.
  259. */
  260. forEach: supportsForEach ? function(array, fn, scope) {
  261. return array.forEach(fn, scope);
  262. } : function(array, fn, scope) {
  263. var i = 0,
  264. ln = array.length;
  265. for (; i &lt; ln; i++) {
  266. fn.call(scope, array[i], i, array);
  267. }
  268. },
  269. <span id='Ext-Array-method-indexOf'> /**
  270. </span> * Get the index of the provided `item` in the given `array`, a supplement for the
  271. * missing arrayPrototype.indexOf in Internet Explorer.
  272. *
  273. * @param {Array} array The array to check
  274. * @param {Object} item The item to look for
  275. * @param {Number} from (Optional) The index at which to begin the search
  276. * @return {Number} The index of item in the array (or -1 if it is not found)
  277. */
  278. indexOf: supportsIndexOf ? function(array, item, from) {
  279. return array.indexOf(item, from);
  280. } : function(array, item, from) {
  281. var i, length = array.length;
  282. for (i = (from &lt; 0) ? Math.max(0, length + from) : from || 0; i &lt; length; i++) {
  283. if (array[i] === item) {
  284. return i;
  285. }
  286. }
  287. return -1;
  288. },
  289. <span id='Ext-Array-method-contains'> /**
  290. </span> * Checks whether or not the given `array` contains the specified `item`
  291. *
  292. * @param {Array} array The array to check
  293. * @param {Object} item The item to look for
  294. * @return {Boolean} True if the array contains the item, false otherwise
  295. */
  296. contains: supportsIndexOf ? function(array, item) {
  297. return array.indexOf(item) !== -1;
  298. } : function(array, item) {
  299. var i, ln;
  300. for (i = 0, ln = array.length; i &lt; ln; i++) {
  301. if (array[i] === item) {
  302. return true;
  303. }
  304. }
  305. return false;
  306. },
  307. <span id='Ext-Array-method-toArray'> /**
  308. </span> * Converts any iterable (numeric indices and a length property) into a true array.
  309. *
  310. * function test() {
  311. * var args = Ext.Array.toArray(arguments),
  312. * fromSecondToLastArgs = Ext.Array.toArray(arguments, 1);
  313. *
  314. * alert(args.join(' '));
  315. * alert(fromSecondToLastArgs.join(' '));
  316. * }
  317. *
  318. * test('just', 'testing', 'here'); // alerts 'just testing here';
  319. * // alerts 'testing here';
  320. *
  321. * Ext.Array.toArray(document.getElementsByTagName('div')); // will convert the NodeList into an array
  322. * Ext.Array.toArray('splitted'); // returns ['s', 'p', 'l', 'i', 't', 't', 'e', 'd']
  323. * Ext.Array.toArray('splitted', 0, 3); // returns ['s', 'p', 'l']
  324. *
  325. * {@link Ext#toArray Ext.toArray} is alias for {@link Ext.Array#toArray Ext.Array.toArray}
  326. *
  327. * @param {Object} iterable the iterable object to be turned into a true Array.
  328. * @param {Number} start (Optional) a zero-based index that specifies the start of extraction. Defaults to 0
  329. * @param {Number} end (Optional) a 1-based index that specifies the end of extraction. Defaults to the last
  330. * index of the iterable value
  331. * @return {Array} array
  332. */
  333. toArray: function(iterable, start, end){
  334. if (!iterable || !iterable.length) {
  335. return [];
  336. }
  337. if (typeof iterable === 'string') {
  338. iterable = iterable.split('');
  339. }
  340. if (supportsSliceOnNodeList) {
  341. return slice.call(iterable, start || 0, end || iterable.length);
  342. }
  343. var array = [],
  344. i;
  345. start = start || 0;
  346. end = end ? ((end &lt; 0) ? iterable.length + end : end) : iterable.length;
  347. for (i = start; i &lt; end; i++) {
  348. array.push(iterable[i]);
  349. }
  350. return array;
  351. },
  352. <span id='Ext-Array-method-pluck'> /**
  353. </span> * Plucks the value of a property from each item in the Array. Example:
  354. *
  355. * Ext.Array.pluck(Ext.query(&quot;p&quot;), &quot;className&quot;); // [el1.className, el2.className, ..., elN.className]
  356. *
  357. * @param {Array/NodeList} array The Array of items to pluck the value from.
  358. * @param {String} propertyName The property name to pluck from each element.
  359. * @return {Array} The value from each item in the Array.
  360. */
  361. pluck: function(array, propertyName) {
  362. var ret = [],
  363. i, ln, item;
  364. for (i = 0, ln = array.length; i &lt; ln; i++) {
  365. item = array[i];
  366. ret.push(item[propertyName]);
  367. }
  368. return ret;
  369. },
  370. <span id='Ext-Array-method-map'> /**
  371. </span> * Creates a new array with the results of calling a provided function on every element in this array.
  372. *
  373. * @param {Array} array
  374. * @param {Function} fn Callback function for each item
  375. * @param {Object} scope Callback function scope
  376. * @return {Array} results
  377. */
  378. map: supportsMap ? function(array, fn, scope) {
  379. //&lt;debug&gt;
  380. if (!fn) {
  381. Ext.Error.raise('Ext.Array.map must have a callback function passed as second argument.');
  382. }
  383. //&lt;/debug&gt;
  384. return array.map(fn, scope);
  385. } : function(array, fn, scope) {
  386. //&lt;debug&gt;
  387. if (!fn) {
  388. Ext.Error.raise('Ext.Array.map must have a callback function passed as second argument.');
  389. }
  390. //&lt;/debug&gt;
  391. var results = [],
  392. i = 0,
  393. len = array.length;
  394. for (; i &lt; len; i++) {
  395. results[i] = fn.call(scope, array[i], i, array);
  396. }
  397. return results;
  398. },
  399. <span id='Ext-Array-method-every'> /**
  400. </span> * Executes the specified function for each array element until the function returns a falsy value.
  401. * If such an item is found, the function will return false immediately.
  402. * Otherwise, it will return true.
  403. *
  404. * @param {Array} array
  405. * @param {Function} fn Callback function for each item
  406. * @param {Object} scope Callback function scope
  407. * @return {Boolean} True if no false value is returned by the callback function.
  408. */
  409. every: supportsEvery ? function(array, fn, scope) {
  410. //&lt;debug&gt;
  411. if (!fn) {
  412. Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.');
  413. }
  414. //&lt;/debug&gt;
  415. return array.every(fn, scope);
  416. } : function(array, fn, scope) {
  417. //&lt;debug&gt;
  418. if (!fn) {
  419. Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.');
  420. }
  421. //&lt;/debug&gt;
  422. var i = 0,
  423. ln = array.length;
  424. for (; i &lt; ln; ++i) {
  425. if (!fn.call(scope, array[i], i, array)) {
  426. return false;
  427. }
  428. }
  429. return true;
  430. },
  431. <span id='Ext-Array-method-some'> /**
  432. </span> * Executes the specified function for each array element until the function returns a truthy value.
  433. * If such an item is found, the function will return true immediately. Otherwise, it will return false.
  434. *
  435. * @param {Array} array
  436. * @param {Function} fn Callback function for each item
  437. * @param {Object} scope Callback function scope
  438. * @return {Boolean} True if the callback function returns a truthy value.
  439. */
  440. some: supportsSome ? function(array, fn, scope) {
  441. //&lt;debug&gt;
  442. if (!fn) {
  443. Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.');
  444. }
  445. //&lt;/debug&gt;
  446. return array.some(fn, scope);
  447. } : function(array, fn, scope) {
  448. //&lt;debug&gt;
  449. if (!fn) {
  450. Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.');
  451. }
  452. //&lt;/debug&gt;
  453. var i = 0,
  454. ln = array.length;
  455. for (; i &lt; ln; ++i) {
  456. if (fn.call(scope, array[i], i, array)) {
  457. return true;
  458. }
  459. }
  460. return false;
  461. },
  462. <span id='Ext-Array-method-clean'> /**
  463. </span> * Filter through an array and remove empty item as defined in {@link Ext#isEmpty Ext.isEmpty}
  464. *
  465. * See {@link Ext.Array#filter}
  466. *
  467. * @param {Array} array
  468. * @return {Array} results
  469. */
  470. clean: function(array) {
  471. var results = [],
  472. i = 0,
  473. ln = array.length,
  474. item;
  475. for (; i &lt; ln; i++) {
  476. item = array[i];
  477. if (!Ext.isEmpty(item)) {
  478. results.push(item);
  479. }
  480. }
  481. return results;
  482. },
  483. <span id='Ext-Array-method-unique'> /**
  484. </span> * Returns a new array with unique items
  485. *
  486. * @param {Array} array
  487. * @return {Array} results
  488. */
  489. unique: function(array) {
  490. var clone = [],
  491. i = 0,
  492. ln = array.length,
  493. item;
  494. for (; i &lt; ln; i++) {
  495. item = array[i];
  496. if (ExtArray.indexOf(clone, item) === -1) {
  497. clone.push(item);
  498. }
  499. }
  500. return clone;
  501. },
  502. <span id='Ext-Array-method-filter'> /**
  503. </span> * Creates a new array with all of the elements of this array for which
  504. * the provided filtering function returns true.
  505. *
  506. * @param {Array} array
  507. * @param {Function} fn Callback function for each item
  508. * @param {Object} scope Callback function scope
  509. * @return {Array} results
  510. */
  511. filter: supportsFilter ? function(array, fn, scope) {
  512. //&lt;debug&gt;
  513. if (!fn) {
  514. Ext.Error.raise('Ext.Array.filter must have a callback function passed as second argument.');
  515. }
  516. //&lt;/debug&gt;
  517. return array.filter(fn, scope);
  518. } : function(array, fn, scope) {
  519. //&lt;debug&gt;
  520. if (!fn) {
  521. Ext.Error.raise('Ext.Array.filter must have a callback function passed as second argument.');
  522. }
  523. //&lt;/debug&gt;
  524. var results = [],
  525. i = 0,
  526. ln = array.length;
  527. for (; i &lt; ln; i++) {
  528. if (fn.call(scope, array[i], i, array)) {
  529. results.push(array[i]);
  530. }
  531. }
  532. return results;
  533. },
  534. <span id='Ext-Array-method-from'> /**
  535. </span> * Converts a value to an array if it's not already an array; returns:
  536. *
  537. * - An empty array if given value is `undefined` or `null`
  538. * - Itself if given value is already an array
  539. * - An array copy if given value is {@link Ext#isIterable iterable} (arguments, NodeList and alike)
  540. * - An array with one item which is the given value, otherwise
  541. *
  542. * @param {Object} value The value to convert to an array if it's not already is an array
  543. * @param {Boolean} newReference (Optional) True to clone the given array and return a new reference if necessary,
  544. * defaults to false
  545. * @return {Array} array
  546. */
  547. from: function(value, newReference) {
  548. if (value === undefined || value === null) {
  549. return [];
  550. }
  551. if (Ext.isArray(value)) {
  552. return (newReference) ? slice.call(value) : value;
  553. }
  554. var type = typeof value;
  555. // Both strings and functions will have a length property. In phantomJS, NodeList
  556. // instances report typeof=='function' but don't have an apply method...
  557. if (value &amp;&amp; value.length !== undefined &amp;&amp; type !== 'string' &amp;&amp; (type !== 'function' || !value.apply)) {
  558. return ExtArray.toArray(value);
  559. }
  560. return [value];
  561. },
  562. <span id='Ext-Array-method-remove'> /**
  563. </span> * Removes the specified item from the array if it exists
  564. *
  565. * @param {Array} array The array
  566. * @param {Object} item The item to remove
  567. * @return {Array} The passed array itself
  568. */
  569. remove: function(array, item) {
  570. var index = ExtArray.indexOf(array, item);
  571. if (index !== -1) {
  572. erase(array, index, 1);
  573. }
  574. return array;
  575. },
  576. <span id='Ext-Array-method-include'> /**
  577. </span> * Push an item into the array only if the array doesn't contain it yet
  578. *
  579. * @param {Array} array The array
  580. * @param {Object} item The item to include
  581. */
  582. include: function(array, item) {
  583. if (!ExtArray.contains(array, item)) {
  584. array.push(item);
  585. }
  586. },
  587. <span id='Ext-Array-method-clone'> /**
  588. </span> * Clone a flat array without referencing the previous one. Note that this is different
  589. * from Ext.clone since it doesn't handle recursive cloning. It's simply a convenient, easy-to-remember method
  590. * for Array.prototype.slice.call(array)
  591. *
  592. * @param {Array} array The array
  593. * @return {Array} The clone array
  594. */
  595. clone: function(array) {
  596. return slice.call(array);
  597. },
  598. <span id='Ext-Array-method-merge'> /**
  599. </span> * Merge multiple arrays into one with unique items.
  600. *
  601. * {@link Ext.Array#union} is alias for {@link Ext.Array#merge}
  602. *
  603. * @param {Array} array1
  604. * @param {Array} array2
  605. * @param {Array} etc
  606. * @return {Array} merged
  607. */
  608. merge: function() {
  609. var args = slice.call(arguments),
  610. array = [],
  611. i, ln;
  612. for (i = 0, ln = args.length; i &lt; ln; i++) {
  613. array = array.concat(args[i]);
  614. }
  615. return ExtArray.unique(array);
  616. },
  617. <span id='Ext-Array-method-intersect'> /**
  618. </span> * Merge multiple arrays into one with unique items that exist in all of the arrays.
  619. *
  620. * @param {Array} array1
  621. * @param {Array} array2
  622. * @param {Array} etc
  623. * @return {Array} intersect
  624. */
  625. intersect: function() {
  626. var intersection = [],
  627. arrays = slice.call(arguments),
  628. arraysLength,
  629. array,
  630. arrayLength,
  631. minArray,
  632. minArrayIndex,
  633. minArrayCandidate,
  634. minArrayLength,
  635. element,
  636. elementCandidate,
  637. elementCount,
  638. i, j, k;
  639. if (!arrays.length) {
  640. return intersection;
  641. }
  642. // Find the smallest array
  643. arraysLength = arrays.length;
  644. for (i = minArrayIndex = 0; i &lt; arraysLength; i++) {
  645. minArrayCandidate = arrays[i];
  646. if (!minArray || minArrayCandidate.length &lt; minArray.length) {
  647. minArray = minArrayCandidate;
  648. minArrayIndex = i;
  649. }
  650. }
  651. minArray = ExtArray.unique(minArray);
  652. erase(arrays, minArrayIndex, 1);
  653. // Use the smallest unique'd array as the anchor loop. If the other array(s) do contain
  654. // an item in the small array, we're likely to find it before reaching the end
  655. // of the inner loop and can terminate the search early.
  656. minArrayLength = minArray.length;
  657. arraysLength = arrays.length;
  658. for (i = 0; i &lt; minArrayLength; i++) {
  659. element = minArray[i];
  660. elementCount = 0;
  661. for (j = 0; j &lt; arraysLength; j++) {
  662. array = arrays[j];
  663. arrayLength = array.length;
  664. for (k = 0; k &lt; arrayLength; k++) {
  665. elementCandidate = array[k];
  666. if (element === elementCandidate) {
  667. elementCount++;
  668. break;
  669. }
  670. }
  671. }
  672. if (elementCount === arraysLength) {
  673. intersection.push(element);
  674. }
  675. }
  676. return intersection;
  677. },
  678. <span id='Ext-Array-method-difference'> /**
  679. </span> * Perform a set difference A-B by subtracting all items in array B from array A.
  680. *
  681. * @param {Array} arrayA
  682. * @param {Array} arrayB
  683. * @return {Array} difference
  684. */
  685. difference: function(arrayA, arrayB) {
  686. var clone = slice.call(arrayA),
  687. ln = clone.length,
  688. i, j, lnB;
  689. for (i = 0,lnB = arrayB.length; i &lt; lnB; i++) {
  690. for (j = 0; j &lt; ln; j++) {
  691. if (clone[j] === arrayB[i]) {
  692. erase(clone, j, 1);
  693. j--;
  694. ln--;
  695. }
  696. }
  697. }
  698. return clone;
  699. },
  700. <span id='Ext-Array-method-slice'> /**
  701. </span> * Returns a shallow copy of a part of an array. This is equivalent to the native
  702. * call &quot;Array.prototype.slice.call(array, begin, end)&quot;. This is often used when &quot;array&quot;
  703. * is &quot;arguments&quot; since the arguments object does not supply a slice method but can
  704. * be the context object to Array.prototype.slice.
  705. *
  706. * @param {Array} array The array (or arguments object).
  707. * @param {Number} begin The index at which to begin. Negative values are offsets from
  708. * the end of the array.
  709. * @param {Number} end The index at which to end. The copied items do not include
  710. * end. Negative values are offsets from the end of the array. If end is omitted,
  711. * all items up to the end of the array are copied.
  712. * @return {Array} The copied piece of the array.
  713. * @method slice
  714. */
  715. // Note: IE6 will return [] on slice.call(x, undefined).
  716. slice: ([1,2].slice(1, undefined).length ?
  717. function (array, begin, end) {
  718. return slice.call(array, begin, end);
  719. } :
  720. // at least IE6 uses arguments.length for variadic signature
  721. function (array, begin, end) {
  722. // After tested for IE 6, the one below is of the best performance
  723. // see http://jsperf.com/slice-fix
  724. if (typeof begin === 'undefined') {
  725. return slice.call(array);
  726. }
  727. if (typeof end === 'undefined') {
  728. return slice.call(array, begin);
  729. }
  730. return slice.call(array, begin, end);
  731. }
  732. ),
  733. <span id='Ext-Array-method-sort'> /**
  734. </span> * Sorts the elements of an Array.
  735. * By default, this method sorts the elements alphabetically and ascending.
  736. *
  737. * @param {Array} array The array to sort.
  738. * @param {Function} sortFn (optional) The comparison function.
  739. * @return {Array} The sorted array.
  740. */
  741. sort: supportsSort ? function(array, sortFn) {
  742. if (sortFn) {
  743. return array.sort(sortFn);
  744. } else {
  745. return array.sort();
  746. }
  747. } : function(array, sortFn) {
  748. var length = array.length,
  749. i = 0,
  750. comparison,
  751. j, min, tmp;
  752. for (; i &lt; length; i++) {
  753. min = i;
  754. for (j = i + 1; j &lt; length; j++) {
  755. if (sortFn) {
  756. comparison = sortFn(array[j], array[min]);
  757. if (comparison &lt; 0) {
  758. min = j;
  759. }
  760. } else if (array[j] &lt; array[min]) {
  761. min = j;
  762. }
  763. }
  764. if (min !== i) {
  765. tmp = array[i];
  766. array[i] = array[min];
  767. array[min] = tmp;
  768. }
  769. }
  770. return array;
  771. },
  772. <span id='Ext-Array-method-flatten'> /**
  773. </span> * Recursively flattens into 1-d Array. Injects Arrays inline.
  774. *
  775. * @param {Array} array The array to flatten
  776. * @return {Array} The 1-d array.
  777. */
  778. flatten: function(array) {
  779. var worker = [];
  780. function rFlatten(a) {
  781. var i, ln, v;
  782. for (i = 0, ln = a.length; i &lt; ln; i++) {
  783. v = a[i];
  784. if (Ext.isArray(v)) {
  785. rFlatten(v);
  786. } else {
  787. worker.push(v);
  788. }
  789. }
  790. return worker;
  791. }
  792. return rFlatten(array);
  793. },
  794. <span id='Ext-Array-method-min'> /**
  795. </span> * Returns the minimum value in the Array.
  796. *
  797. * @param {Array/NodeList} array The Array from which to select the minimum value.
  798. * @param {Function} comparisonFn (optional) a function to perform the comparision which determines minimization.
  799. * If omitted the &quot;&lt;&quot; operator will be used. Note: gt = 1; eq = 0; lt = -1
  800. * @return {Object} minValue The minimum value
  801. */
  802. min: function(array, comparisonFn) {
  803. var min = array[0],
  804. i, ln, item;
  805. for (i = 0, ln = array.length; i &lt; ln; i++) {
  806. item = array[i];
  807. if (comparisonFn) {
  808. if (comparisonFn(min, item) === 1) {
  809. min = item;
  810. }
  811. }
  812. else {
  813. if (item &lt; min) {
  814. min = item;
  815. }
  816. }
  817. }
  818. return min;
  819. },
  820. <span id='Ext-Array-method-max'> /**
  821. </span> * Returns the maximum value in the Array.
  822. *
  823. * @param {Array/NodeList} array The Array from which to select the maximum value.
  824. * @param {Function} comparisonFn (optional) a function to perform the comparision which determines maximization.
  825. * If omitted the &quot;&gt;&quot; operator will be used. Note: gt = 1; eq = 0; lt = -1
  826. * @return {Object} maxValue The maximum value
  827. */
  828. max: function(array, comparisonFn) {
  829. var max = array[0],
  830. i, ln, item;
  831. for (i = 0, ln = array.length; i &lt; ln; i++) {
  832. item = array[i];
  833. if (comparisonFn) {
  834. if (comparisonFn(max, item) === -1) {
  835. max = item;
  836. }
  837. }
  838. else {
  839. if (item &gt; max) {
  840. max = item;
  841. }
  842. }
  843. }
  844. return max;
  845. },
  846. <span id='Ext-Array-method-mean'> /**
  847. </span> * Calculates the mean of all items in the array.
  848. *
  849. * @param {Array} array The Array to calculate the mean value of.
  850. * @return {Number} The mean.
  851. */
  852. mean: function(array) {
  853. return array.length &gt; 0 ? ExtArray.sum(array) / array.length : undefined;
  854. },
  855. <span id='Ext-Array-method-sum'> /**
  856. </span> * Calculates the sum of all items in the given array.
  857. *
  858. * @param {Array} array The Array to calculate the sum value of.
  859. * @return {Number} The sum.
  860. */
  861. sum: function(array) {
  862. var sum = 0,
  863. i, ln, item;
  864. for (i = 0,ln = array.length; i &lt; ln; i++) {
  865. item = array[i];
  866. sum += item;
  867. }
  868. return sum;
  869. },
  870. <span id='Ext-Array-method-toMap'> /**
  871. </span> * Creates a map (object) keyed by the elements of the given array. The values in
  872. * the map are the index+1 of the array element. For example:
  873. *
  874. * var map = Ext.Array.toMap(['a','b','c']);
  875. *
  876. * // map = { a: 1, b: 2, c: 3 };
  877. *
  878. * Or a key property can be specified:
  879. *
  880. * var map = Ext.Array.toMap([
  881. * { name: 'a' },
  882. * { name: 'b' },
  883. * { name: 'c' }
  884. * ], 'name');
  885. *
  886. * // map = { a: 1, b: 2, c: 3 };
  887. *
  888. * Lastly, a key extractor can be provided:
  889. *
  890. * var map = Ext.Array.toMap([
  891. * { name: 'a' },
  892. * { name: 'b' },
  893. * { name: 'c' }
  894. * ], function (obj) { return obj.name.toUpperCase(); });
  895. *
  896. * // map = { A: 1, B: 2, C: 3 };
  897. */
  898. toMap: function(array, getKey, scope) {
  899. var map = {},
  900. i = array.length;
  901. if (!getKey) {
  902. while (i--) {
  903. map[array[i]] = i+1;
  904. }
  905. } else if (typeof getKey == 'string') {
  906. while (i--) {
  907. map[array[i][getKey]] = i+1;
  908. }
  909. } else {
  910. while (i--) {
  911. map[getKey.call(scope, array[i])] = i+1;
  912. }
  913. }
  914. return map;
  915. },
  916. //&lt;debug&gt;
  917. _replaceSim: replaceSim, // for unit testing
  918. _spliceSim: spliceSim,
  919. //&lt;/debug&gt;
  920. <span id='Ext-Array-method-erase'> /**
  921. </span> * Removes items from an array. This is functionally equivalent to the splice method
  922. * of Array, but works around bugs in IE8's splice method and does not copy the
  923. * removed elements in order to return them (because very often they are ignored).
  924. *
  925. * @param {Array} array The Array on which to replace.
  926. * @param {Number} index The index in the array at which to operate.
  927. * @param {Number} removeCount The number of items to remove at index.
  928. * @return {Array} The array passed.
  929. * @method
  930. */
  931. erase: erase,
  932. <span id='Ext-Array-method-insert'> /**
  933. </span> * Inserts items in to an array.
  934. *
  935. * @param {Array} array The Array in which to insert.
  936. * @param {Number} index The index in the array at which to operate.
  937. * @param {Array} items The array of items to insert at index.
  938. * @return {Array} The array passed.
  939. */
  940. insert: function (array, index, items) {
  941. return replace(array, index, 0, items);
  942. },
  943. <span id='Ext-Array-method-replace'> /**
  944. </span> * Replaces items in an array. This is functionally equivalent to the splice method
  945. * of Array, but works around bugs in IE8's splice method and is often more convenient
  946. * to call because it accepts an array of items to insert rather than use a variadic
  947. * argument list.
  948. *
  949. * @param {Array} array The Array on which to replace.
  950. * @param {Number} index The index in the array at which to operate.
  951. * @param {Number} removeCount The number of items to remove at index (can be 0).
  952. * @param {Array} insert (optional) An array of items to insert at index.
  953. * @return {Array} The array passed.
  954. * @method
  955. */
  956. replace: replace,
  957. <span id='Ext-Array-method-splice'> /**
  958. </span> * Replaces items in an array. This is equivalent to the splice method of Array, but
  959. * works around bugs in IE8's splice method. The signature is exactly the same as the
  960. * splice method except that the array is the first argument. All arguments following
  961. * removeCount are inserted in the array at index.
  962. *
  963. * @param {Array} array The Array on which to replace.
  964. * @param {Number} index The index in the array at which to operate.
  965. * @param {Number} removeCount The number of items to remove at index (can be 0).
  966. * @param {Object...} elements The elements to add to the array. If you don't specify
  967. * any elements, splice simply removes elements from the array.
  968. * @return {Array} An array containing the removed items.
  969. * @method
  970. */
  971. splice: splice,
  972. <span id='Ext-Array-method-push'> /**
  973. </span> * Pushes new items onto the end of an Array.
  974. *
  975. * Passed parameters may be single items, or arrays of items. If an Array is found in the argument list, all its
  976. * elements are pushed into the end of the target Array.
  977. *
  978. * @param {Array} target The Array onto which to push new items
  979. * @param {Object...} elements The elements to add to the array. Each parameter may
  980. * be an Array, in which case all the elements of that Array will be pushed into the end of the
  981. * destination Array.
  982. * @return {Array} An array containing all the new items push onto the end.
  983. *
  984. */
  985. push: function(array) {
  986. var len = arguments.length,
  987. i = 1,
  988. newItem;
  989. if (array === undefined) {
  990. array = [];
  991. } else if (!Ext.isArray(array)) {
  992. array = [array];
  993. }
  994. for (; i &lt; len; i++) {
  995. newItem = arguments[i];
  996. Array.prototype.push[Ext.isArray(newItem) ? 'apply' : 'call'](array, newItem);
  997. }
  998. return array;
  999. }
  1000. };
  1001. <span id='Ext-method-each'> /**
  1002. </span> * @method
  1003. * @member Ext
  1004. * @inheritdoc Ext.Array#each
  1005. */
  1006. Ext.each = ExtArray.each;
  1007. <span id='Ext-Array-method-union'> /**
  1008. </span> * @method
  1009. * @member Ext.Array
  1010. * @inheritdoc Ext.Array#merge
  1011. */
  1012. ExtArray.union = ExtArray.merge;
  1013. <span id='Ext-method-min'> /**
  1014. </span> * Old alias to {@link Ext.Array#min}
  1015. * @deprecated 4.0.0 Use {@link Ext.Array#min} instead
  1016. * @method
  1017. * @member Ext
  1018. * @inheritdoc Ext.Array#min
  1019. */
  1020. Ext.min = ExtArray.min;
  1021. <span id='Ext-method-max'> /**
  1022. </span> * Old alias to {@link Ext.Array#max}
  1023. * @deprecated 4.0.0 Use {@link Ext.Array#max} instead
  1024. * @method
  1025. * @member Ext
  1026. * @inheritdoc Ext.Array#max
  1027. */
  1028. Ext.max = ExtArray.max;
  1029. <span id='Ext-method-sum'> /**
  1030. </span> * Old alias to {@link Ext.Array#sum}
  1031. * @deprecated 4.0.0 Use {@link Ext.Array#sum} instead
  1032. * @method
  1033. * @member Ext
  1034. * @inheritdoc Ext.Array#sum
  1035. */
  1036. Ext.sum = ExtArray.sum;
  1037. <span id='Ext-method-mean'> /**
  1038. </span> * Old alias to {@link Ext.Array#mean}
  1039. * @deprecated 4.0.0 Use {@link Ext.Array#mean} instead
  1040. * @method
  1041. * @member Ext
  1042. * @inheritdoc Ext.Array#mean
  1043. */
  1044. Ext.mean = ExtArray.mean;
  1045. <span id='Ext-method-flatten'> /**
  1046. </span> * Old alias to {@link Ext.Array#flatten}
  1047. * @deprecated 4.0.0 Use {@link Ext.Array#flatten} instead
  1048. * @method
  1049. * @member Ext
  1050. * @inheritdoc Ext.Array#flatten
  1051. */
  1052. Ext.flatten = ExtArray.flatten;
  1053. <span id='Ext-method-clean'> /**
  1054. </span> * Old alias to {@link Ext.Array#clean}
  1055. * @deprecated 4.0.0 Use {@link Ext.Array#clean} instead
  1056. * @method
  1057. * @member Ext
  1058. * @inheritdoc Ext.Array#clean
  1059. */
  1060. Ext.clean = ExtArray.clean;
  1061. <span id='Ext-method-unique'> /**
  1062. </span> * Old alias to {@link Ext.Array#unique}
  1063. * @deprecated 4.0.0 Use {@link Ext.Array#unique} instead
  1064. * @method
  1065. * @member Ext
  1066. * @inheritdoc Ext.Array#unique
  1067. */
  1068. Ext.unique = ExtArray.unique;
  1069. <span id='Ext-method-pluck'> /**
  1070. </span> * Old alias to {@link Ext.Array#pluck Ext.Array.pluck}
  1071. * @deprecated 4.0.0 Use {@link Ext.Array#pluck Ext.Array.pluck} instead
  1072. * @method
  1073. * @member Ext
  1074. * @inheritdoc Ext.Array#pluck
  1075. */
  1076. Ext.pluck = ExtArray.pluck;
  1077. <span id='Ext-method-toArray'> /**
  1078. </span> * @method
  1079. * @member Ext
  1080. * @inheritdoc Ext.Array#toArray
  1081. */
  1082. Ext.toArray = function() {
  1083. return ExtArray.toArray.apply(ExtArray, arguments);
  1084. };
  1085. }());
  1086. </pre>
  1087. </body>
  1088. </html>