Plato on Github
Report Home
node_modules\atropa-arrays\src\atropa-arrays.js
Maintainability
73.93
Lines of code
428
Difficulty
43.09
Estimated Errors
0.94
Function weight
By Complexity
By SLOC
/// <reference path="../docs/vsdoc/OpenLayersAll.js"/> var atropa = require('atropa-header'); atropa.inquire = require('atropa-inquire').inquire; /*jslint indent: 4, maxerr: 50, white: true, browser: true, devel: true, plusplus: true, regexp: true */ /*global atropa */ // end header /** * Utilities for handling arrays. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130221 * @namespace Utilities for handling arrays. */ atropa.arrays = {}; /** * Compares two arrays based on size, contents, and element order. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20120909 * @param {Array} array1 One array you want compared to another. * @param {Array} array2 The other array. * @returns {Boolean} Returns true or false depending on * whether or not the arrays matched in size, composition, and * element order. * @example * var x = [1,2]; * var y = [1,1,3]; * atropa.arrays.match(x,y); * // returns false * @example * var x = [1,2]; * var y = [1,2]; * atropa.arrays.match(x,y); * // returns true * @example * var x = [1,2]; * var y = [2,1]; * atropa.arrays.match(x,y); * // returns false because the elements are not in the same order. * @example * var x = [1,{'aProp' : 'aValue'}]; * var y = [1,{'aProp' : 'aValue'}]; * atropa.arrays.match(x,y); * // returns false because even though the object looks the same, the * // two objects are in fact distinct objects. * @example * var obj = {'aProp' : 'aValue'}; * var x = [1,obj]; * var y = [1,obj]; * atropa.arrays.match(x,y); * // returns true because the objects referenced in the arrays are * // in fact the same object. */ atropa.arrays.match = function arraysMatch(array1, array2) { "use strict"; var x, l; if (array1.length !== array2.length) { return false; } l = array1.length; for (x = 0; x < l; x += 1) { if (array1[x] !== array2[x]) { return false; } } return true; }; /** * Subtracts one array from another array based on the unique values in both * sets. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130112 * @param {Array} a (subtrahend) The array to subtract. * @param {Array} fromB (minuend) The array with elements duplicated in <code>a</code> * @returns {Array} Returns a new array containing only the unique * values found in <code>fromB</code> that are not present in <code>a</code> * @example * var x = [1,2]; * var y = [1,1,3]; * atropa.arrays.subtract(x,y); * // returns [3] * @example * var x = [1,3]; * var y = [3,1]; * atropa.arrays.subtract(x,y); * // returns [] * @example * var x = [1,3]; * var y = [3,1,1,9]; * atropa.arrays.subtract(x,y); * // returns [9] * @example * var x = [1,3,{'aProp' : 'aVal'}]; * var y = [3,1,{'aProp' : 'aVal'}]; * atropa.arrays.subtract(x,y); * // returns [{'aProp' : 'aVal'}] * // because the two objects are not the same object. * @example * var obj = {'aProp' : 'aVal'}; * var x = [1,3,obj]; * var y = [3,1,{'aProp' : 'aVal'}]; * atropa.arrays.subtract(x,y); * // returns [{'aProp' : 'aVal'}] * // because the two objects are not the same object. * @example * var obj = {'aProp' : 'aVal'} * var x = [1,3,obj]; * var y = [3,1,obj]; * atropa.arrays.subtract(x,y); * // returns [] * // because the objects referenced in the arrays are the same object. */ atropa.arrays.subtract = function(a, fromB) { "use strict"; var the = {}; the.result = []; fromB.forEach(function(item){ the.mark = false; a.forEach(function(rm){ if(item === rm) { the.mark = true; } }); if(the.mark !== true) { the.result.push(item); } }); return the.result; }; /** * Returns an array of values found in both of the given arrays. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130112 * @param {Array} array1 An array. * @param {Array} array2 Another array. * @returns {Array} Returns an array of values found in both of the given * arrays. * @example * var x = [1,3,4]; * var y = [3,1,5]; * atropa.arrays.intersect(x,y); * // returns [1,3] * @example * var x = [1,1,3,4]; * var y = [3,1,1,5]; * atropa.arrays.intersect(x,y); * // returns [1,1,3] * @example * var obj = {'aProp' : 'aVal'}; * var x = [1,3,obj]; * var y = [3,1,obj]; * atropa.arrays.intersect(x,y); * // returns [1,3,{'aProp' : 'aVal'}] * @example * var obj = {'aProp' : 'aVal'}; * var x = [1,3,{'aProp' : 'aVal'}]; * var y = [3,1,obj]; * atropa.arrays.intersect(x,y); * // returns [1,3] because the two objects are not the same object. * @example * var x = [1,3,{'aProp' : 'aVal'}]; * var y = [3,1,{'aProp' : 'aVal'}]; * atropa.arrays.intersect(x,y); * // returns [1,3] because the two objects are not the same object. */ atropa.arrays.intersect = function intersect(array1, array2) { "use strict"; var smallArray, largeArray, intersection = []; if(array1.length > array2.length) { largeArray = array1.splice(0); smallArray = array2.splice(0); } else { largeArray = array2.splice(0); smallArray = array1.splice(0); } smallArray.forEach(function (item) { var idxInLargeArray = largeArray.indexOf(item); if (0 <= idxInLargeArray) { // has word intersection.push(largeArray.splice(idxInLargeArray, 1)[0]); } }); return intersection; }; /** * Calculates the frequency of items occurring in an array. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130118 * @param {Array} arr The array to calculate frequencies from. * @returns {Object} Returns an object whose keys are each unique * elements from the array and their value is their frequency of * occurrence within the array. Be careful that your array does * not contain values matching object instance property names. * @example * var x = [1,1,1,1,1,3,3]; * atropa.arrays.getFrequency(x); * // returns { * // "1": 5, * // "3": 2 * // } * @example * var x = ["bill", "fred", "fred", "jane"]; * atropa.arrays.getFrequency(x); * // returns { * // "bill": 1, * // "fred": 2, * // "jane": 1 * // } * @example * var x = [1,3,{'aProp' : 'aVal'}]; * atropa.arrays.getFrequency(x); * // returns { * // "1": 1, * // "3": 1, * // "[object Object]": 1 * // } * @example * var obj = {'aProp' : 'aVal'}; * var otherObj = {}; * var x = [1,3,obj,otherObj,{'aDoughnut' : 'sprinkles'}]; * atropa.arrays.getFrequency(x); * // returns { * // "1": 1, * // "3": 1, * // "[object Object]": 3 * // } * @example * var x = [1,3,"toString"]; * atropa.arrays.getFrequency(x); * // returns { * // "1": 1, * // "3": 1, * // "toString": "function toString() {\n [native code]\n}1" * // } */ atropa.arrays.getFrequency = function (arr) { "use strict"; var out = arr.reduce(function (acc, curr) { if (acc[curr] === undefined) { acc[curr] = 1; } else { acc[curr] += 1; } return acc; }, {}); return out; }; /** * Gets Unique values from an array. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130118 * @param {Array} largeArray The array with duplicate values in it. * @returns {Array} Returns a new array containing only the unique * values found in the largeArray. * @example * var x = [1,1,1,4,4,3,6]; * atropa.arrays.getUnique(x); * // returns [ "1", "4", "3", "6" ] * @example * var x = ["bill", "fred", "jane", "fred"]; * atropa.arrays.getUnique(x); * // returns ["bill", "fred", "jane"] * @example * var x = [ * "bill", * {"aProp" : "aValue"}, * {"aGuy" : "fred"}, * {"aLady" : "jane"} * ]; * atropa.arrays.getUnique(x); * // returns [ "bill", "[object Object]" ] */ atropa.arrays.getUnique = function (largeArray) { "use strict"; return Object.keys(atropa.arrays.getFrequency(largeArray)).sort(); }; /** * Removes empty strings from the given array. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130118 * @param {Array} arrayWithEmptyElements The array with empty strings in it. * @returns {Array} Returns a new array with empty strings removed. * @example * var x = [ 10, , 5, "", '', 7 ]; * console.log('starting length ' + x.length); * console.log(x); * x = atropa.arrays.removeEmptyElements(x); * console.log('ending length ' + x.length); * console.log(x); * // displays the following * // starting length 6 * // [10, undefined, 5, "", "", 7] * // ending length 3 * // [10, 5, 7] */ atropa.arrays.removeEmptyElements = function (arrayWithEmptyElements) { "use strict"; return arrayWithEmptyElements.filter(function (item) { return !atropa.inquire.isEmptyString(item); }); }; /** * Reindexes an array. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130118 * @param {Array} arr The array with discontinuous keys. * @returns {Array} Returns an array with continuous keys. * @example * var x = [ "a", "b", "c", undefined ]; * console.log(x); // [ "a", "b", "c", undefined ] * console.log(x.length); // 4 * * delete x[1]; // deletes the key from the array but * // the array length remains the same * // at this point the arrays keys are 0, 2, and 3 * console.log(x); // [ "a", undefined, "c", undefined ] * console.log(x.length); // 4 * * x = atropa.arrays.reindex(x); * console.log(x); // [ "a", "c", undefined ] * // note that the last element existed in the array, its value was * // undefined but it did have a key so the element remains in the array. * // * // The deleted element was in fact deleted from the array so there was no * // key x[1] at all, when trying to access this non existing element the * // value of undefined was returned. This behavior is confusing unless you * // think about the arrayas an object whose properties are named by * // numbers. Accessing an undefined property returns undefined regardless * // of whether the property existed in the past or not. * console.log(x.length); // 3 */ atropa.arrays.reindex = function reindex(arr) { "use strict"; var idx, out; out = []; for(idx in arr) { if(arr.hasOwnProperty(idx)) { out.push(arr[idx]); } } return out; }; /** * Sorts an array's elements numerically. * @author <a href="mailto:matthewkastor@gmail.com"> * Matthew Christopher Kastor-Inare III </a><br /> * ☭ Hial Atropa!! ☭ * @version 20130120 * @param {Array} arr The array to sort. All elements of the array must be * number-ish. * @returns {Array} Returns an array whose elements are in numeric order. * @example * var x = [3, 2, 9, 26, 10, 1, 99, 15]; * console.log( atropa.arrays.sortNumerically(x) ); * // logs [1, 2, 3, 9, 10, 15, 26, 99] */ atropa.arrays.sortNumerically = function sortNumerically(arr) { "use strict"; return arr.sort(function (a, b) { return (a - b); }); }; /** * Throws an error, <code>String.prototype.localeCompare</code> is not * standardized. * * Yes, localeCompare is in the standard but, at this time the actual * comparison is implementation dependant. This means that "alphabetical order" * can be different on different platforms. What I found was that in node the * array of <code>['a','Z','A','z']</code> would be sorted to * <code>['A','Z','a','z"]</code>, while on * firefox it would be sorted to <code>['a','A','z','Z']</code>. Who knows if * another implementor would sort it <code>['A','a','Z','z']</code>? * * In order to provide a reliable implementation I would have to create my own * implementation of <code>String.prototype.localeCompare</code> and that's * just too much work for me to do alone. * @throws {Error} "String.prototype.localeCompare is not standardized" */ atropa.arrays.sortAlphabetically = function sortAlphabetically(arr) { "use strict"; throw new Error("String.prototype.localeCompare is not standardized"); }; /** * Deletes the given element from the array at the given index. It basically * does what you would expect the delete operator to do, except the delete * operator doesn't do what you would expect. * @param {Array} arr The array. * @param {Number} index The index of the element to delete. * @returns Returns an array with the element removed, contiguous keys, and * whose length is 1 less than the input array. */ atropa.arrays.deleteElement = function (arr, index) { "use strict"; delete arr[index]; return atropa.arrays.reindex(arr); }; while(atropa.data.requirements.length > 0) { atropa.data.requirements.pop()(); } module.exports = atropa;