1// Array Extensions v1.0.7 2// documentation: http://www.dithered.com/javascript/array/index.html 3// license: http://creativecommons.org/licenses/by/1.0/ 4// code by Chris Nott (chris[at]dithered[dot]com) 5// code by Ilya Lebedev (ilya[at]lebedev[dot]net) 6 7 8// Array.concat() - Join two arrays 9if (isUndefined(Array.prototype.concat)) { 10 Array.prototype.concat = function (secondArray) { 11 var firstArray = this.copy(); 12 for (var i = 0, saL = secondArray.length; i < saL; i++) { 13 firstArray[firstArray.length] = secondArray[i]; 14 } 15 return firstArray; 16 }; 17} 18 19// Array.copy() - Copy an array 20if (isUndefined(Array.prototype.copy)) { 21 Array.prototype.copy = function() { 22 var copy = new Array(); 23 for (var i = 0, tL = this.length; i < tL; i++) { 24 copy[i] = this[i]; 25 } 26 return copy; 27 }; 28} 29 30// Array.pop() - Remove the last element of an array and return it 31if (isUndefined(Array.prototype.pop)) { 32 Array.prototype.pop = function() { 33 var lastItem = undefined; 34 if ( this.length > 0 ) { 35 lastItem = this[this.length - 1]; 36 this.length--; 37 } 38 return lastItem; 39 }; 40} 41 42// Array.push() - Add an element to the end of an array 43if (isUndefined(Array.prototype.push)) { 44 Array.prototype.push = function() { 45 var currentLength = this.length; 46 for (var i = 0; i < arguments.length; i++) { 47 this[currentLength + i] = arguments[i]; 48 } 49 return this.length; 50 }; 51} 52 53// Array.shift() - Remove the first element of an array and return it 54if (isUndefined(Array.prototype.shift)) { 55 Array.prototype.shift = function() { 56 var firstItem = this[0]; 57 for (var i = 0, tL = this.length - 1; i < tL; i++) { 58 this[i] = this[i + 1]; 59 } 60 this.length--; 61 return firstItem; 62 }; 63} 64 65// Array.slice() - Copy several elements of an array and return them 66if (isUndefined(Array.prototype.slice)) { 67 Array.prototype.slice = function(start, end) { 68 var temp; 69 70 if (end == null || end == '') end = this.length; 71 72 // negative arguments measure from the end of the array 73 else if (end < 0) end = this.length + end; 74 if (start < 0) start = this.length + start; 75 76 // swap limits if they are backwards 77 if (end < start) { 78 temp = end; 79 end = start; 80 start = temp; 81 } 82 83 // copy elements from array to a new array and return the new array 84 var newArray = new Array(); 85 for (var i = 0; i < end - start; i++) { 86 newArray[i] = this[start + i]; 87 } 88 return newArray; 89 }; 90} 91 92// Array.splice() - Splice out and / or replace several elements of an array and return any deleted elements 93if (isUndefined(Array.prototype.splice)) { 94 Array.prototype.splice = function(start, deleteCount) { 95 if (deleteCount == null || deleteCount == '') deleteCount = this.length - start; 96 97 // create a temporary copy of the array 98 var tempArray = this.copy(); 99 100 // Copy new elements into array (over-writing old entries) 101 for (var i = start, aL = start + arguments.length - 2; i < aL; i++) { 102 this[i] = arguments[i - start + 2]; 103 } 104 105 // Copy old entries after the end of the splice back into array and return 106 var dC = deleteCount - arguments.length + 2; 107 for (var i = start + arguments.length - 2, tL = this.length - deleteCount + arguments.length - 2; i < tL; i++) { 108 this[i] = tempArray[i + dC]; 109 } 110 this.length = this.length - dC; 111 return tempArray.slice(start, start + deleteCount); 112 }; 113} 114 115// Array.unshift - Add an element to the beginning of an array 116if (isUndefined(Array.prototype.unshift)) { 117 Array.prototype.unshift = function(the_item) { 118 for (var loop = this.length-1 ; loop >= 0; loop--) { 119 this[loop+1] = this[loop]; 120 } 121 this[0] = the_item; 122 return this.length; 123 }; 124} 125 126// Array.indexOf - return index of found element or -1 (similar to String.indexOf) 127// Don't do the check on 'undefined' because Mozilla does calculate index weirdly 128Array.prototype.indexOf = function(needle,begin) { 129 for (var i=(null==begin||isNaN(begin)||begin<0)?0:Math.round(begin),len = this.length, idx = -1; idx==-1 & i<len; i++) { 130 idx = (this[i]==needle)?i:idx; 131 } 132 return idx; 133}; 134// Array.lastIndexOf - return index of found element or -1 (similar to String.lastIndexOf) 135// Don't do the check on 'undefined' because Mozilla does calculate index weirdly 136Array.prototype.lastIndexOf = function(needle,end) { 137 for (var i=(null==end||isNaN(end)||end>this.length)?this.length-1:Math.round(end), idx = -1; idx==-1 & i>-1; i--) { 138 idx = (this[i]==needle)?i:idx; 139 } 140 return idx; 141}; 142// Array.map - maps a function on the array elements 143if (isUndefined(Array.prototype.map)) { 144 Array.prototype.map = function(func) { 145 if ('function' != typeof func) return this; 146 var tmp = []; 147 for (var loop = this.length-1 ; loop >= 0; loop--) { 148 tmp[loop] = func(this[loop]); 149 } 150 return tmp; 151 }; 152} 153 154if (isUndefined(Array.prototype.unique)) { 155 /** 156 * Method removes dumplicate entries 157 * 158 * @return {Array} 159 * @scope public 160 */ 161 Array.prototype.unique = function() /* :Array */{ 162 var tmp = []; 163 for(var i=0, tL=this.length; i<tL; i++ ) { 164 if( tmp.indexOf(this[i]) < 0 ) tmp[tmp.length] = this[i]; 165 } 166 return tmp; 167 }; 168} 169 170if (isUndefined(Array.prototype.flatten)) { 171 /** 172 * Method flattens 2-dimensional array, when no cols supplied only the cols number from 0th row will be counted 173 * 174 * @param {Number, Array} cols columns to insert to resulting array 175 * @return {Array} 176 * @scope public 177 */ 178 Array.prototype.flatten = function(cols /* :Array */, cd) /* :Array */{ 179 if (this.length<1) return []; 180 if (isNumeric(cols)) cols = [cols]; 181 var idx = false; 182 if (isArray(cols)) { 183 idx = {}; 184 for (var i=0,cL=cols.length;i<cL;i++) idx[cols[i]]=true; 185 } 186 var tmp = []; 187 for (var i=0, tL=this.length; i<tL; i++ ) { 188 if (isUndefined(this[i])) continue; 189 if (!isArray(this[i])) { 190 if (false===idx) tmp[tmp.length] = this[i]; 191 } else { 192 for (var k=0, cL=this[i].length; k<cL; k++) { 193 if (false===idx || idx.hasOwnProperty(k)) tmp[tmp.length] = this[i][k]; 194 } 195 } 196 } 197 return tmp; 198 }; 199} 200//----------------------------------------------------------------------------- 201// STATIC METHODS 202//----------------------------------------------------------------------------- 203if (isUndefined(Array.range)) { 204 /** 205 * Method creates the array with values in the specified range 206 * 1 argument: create array from min(0, end) to max(0, end) with increment 1 207 * 2 arguments: create array from min(start, end) to max(start, end) with increment 1 208 * 3 arguments: create array from min(start, end) to max(start, end) with increment inc 209 * 210 * @param {Number} end end position 211 * @param {Number} start start position 212 * @param {Number} inc increment 213 * @return {Array} 214 * @scope public 215 */ 216 Array.range = function(end /* :Number */, start /* :Number */, inc /* :Number */) /* :Array */{ 217 if (!isNumber(end)) return null; 218 if (!isNumber(inc)) inc = 1; 219 if (!isNumber(start)) start = 0; 220 var tmp = [] 221 ,mn = Math.min(start, end) 222 ,mx = Math.max(start, end) 223 ,i = Math.abs(inc) 224 ,cnt = -1; 225 do { 226 cnt++; 227 tmp[cnt] = mn; 228 mn += i; 229 } while (mn<=mx); 230 return inc>0?tmp:tmp.reverse(); 231 }; 232} 233