Coverage

91.8%
158
145
13

LineHitsSource

/home/luis/noboxout/js-array-enhancements/index.js

100.0%
3
3
0
LineHitsSource
11(function () {
21 "use strict";
3
41 module.exports = require("/home/luis/noboxout/js-array-enhancements/./lib/arrays.js");
5
6}());

/home/luis/noboxout/js-array-enhancements/lib/arrays.js

91.6%
155
142
13
LineHitsSource
11(function () {
21 "use strict";
3
4/**
5* TODO
6* - some mozilla functions use .call but thisp could be "undefined" so -> can be replaced by direct call ?!
7*
8*/
9
101 var slice = Array.prototype.slice,
11 hasOwnProperty = Object.hasOwnProperty,
12 __clone,
13 __rfilter;
14
15 /**
16 * Create an array given any type of argument
17 *
18 * @param {Mixed} item
19 * @returns {Array}
20 */
211 module.exports.ize = function (item) {
226 if (item === null || item === undefined) {
230 return [];
24 }
25
266 if (item instanceof Array) {
270 return item;
28 }
29
306 if (hasOwnProperty.call(item, "callee")) {
311 return slice.call(item);
32 }
33
34 // TODO deal with Iterable objects like Collections!
35
365 return [ item ];
37 };
38
391 module.exports.from = Array.ize;
40
41 /**
42 * Append any given number of arrays into a new one
43 * @todo support any type of arguments
44 *
45 * @returns Array
46 */
471 module.exports.add = function () {
482 var i,
49 j,
50 ret = [],
51 ar;
52
532 for (i = 0; i < arguments.length; ++i) {
545 ar = arguments[i];
555 for (j = 0; j < ar.length; ++j) {
5615 ret.push(ar[j]);
57 }
58 }
59
602 return ret;
61 };
62 /**
63 * Clone (could be recursive) a dense array
64 * Note: only loop arrays not objects
65 *
66 * @param Array ar
67 * @param Boolean deep
68 * @returns Array
69 */
701 module.exports.clone = __clone = function (ar, deep) {
714 var i = ar.length,
72 clone = new Array(i);
734 while (i--) {
7412 if (deep && ar[i] instanceof Array) {
750 clone[i] = __clone(ar[i], true);
76 } else {
7712 clone[i] = ar[i];
78 }
79 }
804 return clone;
81 };
82 /**
83 * Add an element at the specified index
84 *
85 * @param {Array} ar
86 * @param {Mixed} o The object to add
87 * @param {int} index The index position the element has to be inserted
88 * @return {Boolean} true if o is successfully inserted
89 */
901 module.exports.insertAt = function (ar, o, index) {
915 if (index > -1 && index <= ar.length) {
923 ar.splice(index, 0, o);
933 return true;
94 }
952 return false;
96 };
97 /**
98 * Get a random value, the array must be dense
99 *
100 * @param {Array} arr
101 * @returns {Mixed}
102 */
1031 module.exports.random = function (arr) {
1046 var l = Math.floor(Math.random() * arr.length);
1056 return arr[l];
106 };
107 /**
108 * Create a new array removing duplicated values
109 *
110 * @param {Array} arr
111 * @returns {Array}
112 */
1131 module.exports.unique = function (arr) {
1141 var ret = [],
115 i;
116
1171 for (i = 0; i < arr.length; ++i) {
11818 if (ret.indexOf(arr[i]) === -1) {
11910 ret.push(arr[i]);
120 }
121 }
122
1231 return ret;
124 };
125
126 /**
127 * sort an array (must be dense)
128 *
129 * @param {Array} arr
130 * @returns {Array}
131 */
1321 module.exports.sortObject = function (arr, key) {
1332 arr.sort(function (a, b) {
13412 if ("string" === (typeof a[key])) {
1356 return a.value.toLowerCase().localeCompare(b.value.toLowerCase());
136 }
1376 return a[key] - b[key];
138 });
139
1402 return arr;
141 };
142 /**
143 * This function shuffles (randomizes the order of the elements in) an array.
144 * credits - http://stackoverflow.com/questions/2450954/how-to-randomize-a-javascript-array
145 * @note Given array is modified!
146 * @param {Array} arr
147 * @returns {Array}
148 */
1491 module.exports.shuffle = function (arr) {
1501 var currentIndex = arr.length,
151 temporaryValue,
152 randomIndex;
153
154 // While there remain elements to shuffle..
1551 while (0 !== currentIndex) {
156
157 // Pick a remaining element..
1583 randomIndex = Math.floor(Math.random() * currentIndex);
1593 currentIndex -= 1;
160
161 // And swap it with the current element.
1623 temporaryValue = arr[currentIndex];
1633 arr[currentIndex] = arr[randomIndex];
1643 arr[randomIndex] = temporaryValue;
165 }
166
1671 return arr;
168 };
169
170 /**
171 * Iterates over each value in the array passing them to the callback function.
172 * Returns an array with all the callback results
173 * @param {Array} arr
174 * @param {Function} fun
175 * @returns {Array}
176 */
1771 module.exports.rfilter = __rfilter = function (arr, fun /*, thisp */) {
1783 if (arr === null) {
1790 throw new TypeError();
180 }
181
1823 var t = Object(arr),
183 len = t.length >>> 0,
184 res,
185 thisp,
186 i,
187 val,
188 r;
189
1903 if ("function" !== typeof fun) {
1910 throw new TypeError();
192 }
193
1943 res = [];
1953 thisp = arguments[1];
1963 for (i = 0; i < len; i++) {
19712 if (i in t) {
19812 val = t[i]; // in case fun mutates this
19912 r = fun.call(thisp, val, i, t);
20012 if (r !== undefined) {
2015 res.push(r);
202 }
203 }
204 }
205
2063 return res;
207 };
208
2091 module.exports.chunk = function (arr, size, preserve_keys) {
2102 preserve_keys = preserve_keys || false;
211
2122 var i = 0,
213 j = 0,
214 key,
215 val,
216 chunks = [[]];
217
218 //while( @list( $key, $value ) = @each( arr ) ) {
2192 for (key = 0; key < arr.length; ++key) {
22010 val = arr[key];
221
222
22310 if (chunks[i].length < size) {
2245 if (preserve_keys) {
2252 chunks[i][key] = val;
2262 j++;
227 } else {
2283 chunks[i].push(val);
229 }
230 } else {
2315 i++;
2325 chunks.push([]);
233
2345 if (preserve_keys) {
2353 chunks[i][key] = val;
2363 j++;
237 } else {
2382 j = 0;
2392 chunks[i][j] = val;
240 }
241 }
242 }
243
2442 return chunks;
245 };
246 /**
247 * returns the values from a single column of the array-of-objects/arrays, identified by the column_key.
248 * Optionally, you may provide an index_key to index the values in the returned array by the values from the index_key column in the input array.
249 */
2501 module.exports.column = function (arr, field) {
2510 return Array.rfilter(arr, function (x) { return x ? x[field] : undefined; });
252 };
253 /**
254 * Append any number of arrays into the first one
255 *
256 * @param {Array} dst
257 * @returns {Array}
258 */
2591 module.exports.combine = function (dst) {
2602 var i,
261 j,
262 ar;
263
2642 for (j = 1; j < arguments.length; ++j) {
2653 ar = arguments[j];
266
2673 for (i = 0; i < ar.length; ++i) {
2687 dst.push(ar[i]);
269 }
270 }
271 };
272 /**
273 * Counts all the values of an array
274 */
2751 module.exports.countValues = function (arr, ci) {
2762 ci = ci || false;
2772 var i,
278 counter = {},
279 val;
280
2812 for (i = 0; i < arr.length; ++i) {
28222 val = arr[i];
28322 if (ci && "string" === typeof val) {
28410 val = val.toLowerCase();
285 }
286
28722 if (counter[val]) {
28811 ++counter[val];
289 } else {
29011 counter[val] = 1;
291 }
292 }
293
2942 return counter;
295 };
296 /**
297 * Returns a copy of the array padded to size specified by size with value value. If size is positive then the array is padded on the right, if it"s negative then on the left. If the absolute value of size is less than or equal to the length of the array then no padding takes place
298 */
2991 module.exports.pad = function (arr, size, value) {
3003 if (Math.abs(size) <= arr.length) {
3011 return arr;
302 }
3032 var out = [],
304 i,
305 len;
306
3072 if (size > 0) {
3081 for (i = 0; i < size; ++i) {
3095 out[i] = i < arr.length ? arr[i] : value;
310 }
311 } else {
3121 size = Math.abs(size);
3131 len = size - arr.length;
3141 for (i = 0; i < size; ++i) {
3157 out[i] = i < len ? value : arr[i - len];
316 }
317 }
318
3192 return out;
320 };
321 /**
322 * Calculate the product of values in an array
323 */
3241 module.exports.product = function (arr) {
3251 var sum = 1,
326 len = arr.length,
327 i;
328
3291 for (i = 0; i < len; i++) {
3304 sum *= parseFloat(arr[i]); // be sure it"s a number..
331 }
332
3331 return sum;
334 };
335 /**
336 * Picks one or more random entries out of an array, and returns the key (or keys) of the random entries.
337 */
3381 module.exports.rand = function (arr, len) {
3390 var out = [],
340 i;
3410 len = len || 1;
342
3430 for (i = 0; i < len; ++i) {
3440 out.push(Math.floor(Math.random() * arr.length));
345 }
346
3470 return out;
348 };
349
3501 module.exports.dense = function (arr) {
3511 var out = [];
352
3531 arr.forEach(function (val) {
3542 out.push(val);
355 });
356
3571 return out;
358 };
359
3601 module.exports.sum = function (arr) {
3613 var sum = 0,
362 len = arr.length,
363 i;
364
3653 for (i = 0; i < len; i++) {
36612 sum += parseFloat(arr[i]); // be sure it"s a number..
367 }
368
3693 return sum;
370 };
371
372 /**
373 * Fill an array with values
374 */
3751 module.exports.fill = function (start, count, value) {
3762 var arr = [],
377 len = start + count,
378 i;
379
3802 for (i = start; i < len; ++i) {
38110 arr[i] = value;
382 }
383
3842 return arr;
385 };
386 /**
387 * Return the values from a single column in the input array
388 */
3891 module.exports.column = function (arr, field) {
39015 return __rfilter(arr, function (x) { return x[field]; });
391 };
392
393 /**
394 * returns an object with the same values keys given a property of the object
395 * @throws if the field is undefined!
396 */
3971 module.exports.kmap = function (arr, field) {
3981 var ret = {};
399
4001 arr.forEach(function (v) {
4013 if (!v[field]) {
4020 console.log(v);
4030 throw new Error("field not found in v");
404 }
405
4063 ret[v[field]] = v;
407 });
408
4091 return ret;
410 };
411
412}());