UNPKG

e-structures

Version:

Extended data structures library for JavaScript

287 lines (249 loc) 8 kB
/** * Creates an empty List. * @class A List is a data structure that declares the behavior of a collection * that stores a sequence of elements. * The list class can be used on its own, but it is defined as abstract as possible * that any class extending it can set rules about operations that can be perfomed on the collection * @constructor */ var eList = function () { /** * Define all utility functions here... */ var isObjectOf = function (object) { if (typeof object !== 'object') { return false; } if (!object.hasOwnProperty('getType')) { return false; } if (object.getType() !== 'eList') { return false; } }; var isValidIndex = function (number) { return !((typeof number !== 'number') || (number % 1 !== 0) || (number < 0)); }; // object containing all properties and functions of the list var list = {}; /** * Function to get type of eStructure object */ list.getType = function () { return 'eList'; }; /** * Private array property to hold all elements added to the list */ var data = []; /** * Function to get size of eList */ list.size = function () { return data.length; }; /** * Adds an element to the list. * @param {Integer} index - Optional index to add the element. If no index is specified * the element is added to the end of the list. * @param {Object} item - Element to be added (must always be present). * @return {Integer} Non-negative integer if the element was added or -1 if error occurs */ list.add = function (index, item) { // if arguments.length === 0 || > 2, throw error if (arguments.length === 0 || arguments.length > 2) { return -1; } // if arguments.length === 1, treat as element to be inserted and insert as last element of list if (arguments.length === 1) { data.push(arguments[0]); return list.size(); } // if arguments.length === 2, treat first as index and second as item if (arguments.length === 2) { // check if specified index is a number if (isValidIndex(index) === false) { return -1; } // all checks passed, insert into list if (data.length - 1 < index) { // push into array data.push(item); return list.size(); } else if (index < data.length - 1) { // splice array and insert item data.splice(index, 0, item); return list.size(); } } return -1; }; /** * Adds another eList to the list. * @param {Integer} index - Optional index to add the eList. If no index is specified * the eList is added to the end of the list. * @param {Object} eList - List to be added (must always be present). * @return {Integer} Non-negative integer if the eList was added or -1 if error occurs */ list.addAll = function (index, eList) { // if arguments.length === 0 || > 2, throw error if (arguments.length === 0 || arguments.length > 2) { return -1; } // if arguments.length === 1, treat as eList to be inflated and insert as last element of list if (arguments.length === 1) { // check if argument is an eList if (isObjectOf(arguments[0]) === false) { return null; } data = data.concat(arguments[0].toArray()); return list.size(); } // if arguments.length === 2, treat first as index and second as item if (arguments.length === 2) { // check if specified index is a number if (isValidIndex(index) === false) { return -1; } // check if argument is an eList if (isObjectOf(eList) === false) { return null; } // all checks passed, insert into list if (data.length - 1 < index) { // append new eList to current data = data.concat(eList.toArray()); return list.size(); } else if (index < data.length - 1) { // go through array and splice at incrementing index eList.getIterator().iterate(function (item, currentPosition) { data.splice(index, 0, item); index++; }); return list.size(); } } return -1; }; /** * Replace the element in specified index with povided element * @param {Integer} index - index to of element to be replaced * @param {Object} item - new element to be placed in specified index * @return {Integer} positive integer if element is replaced successfully, -1 if error occurs */ list.set = function (index, item) { // if arguments.length === 0 || > 2, throw error if (arguments.length < 2 || arguments.length > 2 || isValidIndex(index) === false || index > list.size() - 1) { return -1; } // perform replacement data[index] = item; return data[index]; }; /** * Retrieve an element to the list. * @param {Integer} index - index of element to be retrieved * @return {Object} Object at index if found, -1 if error occur */ list.get = function (index) { // validate argument provided if (index === undefined || index < 0 || list.size() === 0 || arguments.length > 1 || index >= list.size()) { return -1; } if (isValidIndex(index) === false) { return -1; } return data[index]; }; /** * Delete element in specified index * @return {Object} Array containing removed element */ list.remove = function (index) { // validate argument provided if (index === undefined || index < 0 || list.size() === 0 || arguments.length > 1 || index >= list.size()) { return -1; } if (isValidIndex(index) === false) { return -1; } return data.splice(index, 1); }; /** * @return {Array} Array containing all eList elements or empty array if eList is empty */ list.toArray = function () { return data; }; /** * @return {String} String containing all eList elements or empty string if eList is empty */ list.toString = function () { return data.toString(); }; /** * ForEach function to loop through eList elements * @param {Function} callBack - callBack function to be provided on each element */ list.forEach = function (callBack) { list.getIterator().iterate(callBack); }; /** * Private iterator property to be used to loop through list elements */ var iterator = { currentPosition: 0, next: function () { var item = list.get(list.getIterator().currentPosition); this.currentPosition += 1; return item; }, hasNext: function () { return this.currentPosition < list.size(); }, iterate: function (callBack) { while (list.getIterator().hasNext()) { callBack(list.getIterator().next(), list.getIterator().currentPosition); } list.getIterator().reset(); }, reset: function () { list.getIterator().currentPosition = 0; } }; /** * Get iterator object * @return {Object} Iterator containing useful functions * to be used to easily loop through all list elements */ list.getIterator = function () { return iterator; }; /** * Returns boolean * @param {Object} list - LinkedList to compare against * @param {Function} compareFunction - Function to use as to compare two objects */ list.equal = function (list, compareFunction) { if (!list || !list.hasOwnProperty('getType') || list.getType() !== 'eList') { return false; } if (this.size() !== list.size()) { return false; } var callBack = compareFunction || eCompare; var isEqual = true; var isNotEqual = true; this.forEach(function (data, position) { var status = callBack(list.get(position - 1), data); if (!status) { isNotEqual = status; } else { isEqual = status; } }); return !isNotEqual ? isNotEqual : isEqual; }; return list; }; eGlobal.eList = eList;