diff --git a/AroTable.js b/AroTable.js index f0a27ad..a2adb35 100644 --- a/AroTable.js +++ b/AroTable.js @@ -24,7 +24,6 @@ export default class AroTable { #neg = {}; #negLength = 0; #array = []; - #indices = {}; /** * Creates an AroTable. Works like an overloaded constructor, it could take no arguments, or it could take a single integer or multiple integers could be passed, or an array, or better still a combination of both. * @param data @@ -34,257 +33,219 @@ export default class AroTable { this.add(data, ...values); } - #aroSort (array) { - return array === null || array === undefined ? - ([])() : array.length <= 1 ? - (array)() : - (() => { - const pos = {}, neg = {}, sorted = []; - let negLength = 0, counter = 1; - - for (let index = 0; index < array.length; index++) (() => { - let element = Number(array[index]); - element < 0 ? - (() => { - element *= -1; - neg[element] ? - neg[element]++ : - neg[element] = 1; - negLength++; - })() : - pos[element] ? - pos[element]++ : - pos[element] = 1; - })(); - (negLength) && (() => { - for (const numValue in neg) (() => { - neg[numValue] > 1 ? - (() => { - for (let i = 0; i < neg[numValue]; i++) - (() => { - sorted[negLength - counter] = Number(numValue) * -1; - counter++; - })(); - })() : - (() => { - sorted[negLength - counter] = Number(numValue) * -1; - counter++; - })(); - })(); - })(); - - (Object.keys(pos).length) && - (() => { - for (const numValue in pos) (() => { - pos[numValue] > 1 ? - (() => { - for (let i = 0; i < pos[numValue]; i++) (() => { - sorted[negLength] = Number(numValue); - negLength++; - })(); - })() : - (() => { - sorted[negLength] = Number(numValue); - negLength++; - })(); - })(); - })(); - return sorted; - })(); + #mergeSort (array) { + if (array.length <= 1) return array; + + const middle_index = Math.floor(array.length / 2), + left_values = this.#mergeSort(array.slice(0, middle_index)), + right_values = this.#mergeSort(array.slice(middle_index)), + left_length = left_values.length, + right_length = right_values.length; + + let left_index = 0, + right_index = 0, + sorted_values = []; + + while (left_index < left_length && right_index < right_length) + left_values[left_index] < right_values[right_index] ? + (sorted_values.push(left_values[left_index]), + left_index++) + : + (sorted_values.push(right_values[right_index]), + right_index++); + + sorted_values = sorted_values.concat(left_values.slice(left_index)), + sorted_values = sorted_values.concat(right_values.slice(right_index)); + + return sorted_values; }; #arrange () { let counter = 1; - (() => { - this.#indices = {}; - this.#array = []; - (this.#negLength > 0) && - (() => { - for (const numValue in this.#neg) { - isNaN(numValue) && (() => false)(); - - if (this.#neg[numValue] > 1) - (() => { - for (let i = 0; i < this.#neg[numValue]; i++) (() => { - this.#array[this.#negLength - counter] = Number(numValue) * -1; - - this.#indices[numValue * -1] ? - this.#indices[numValue * -1] = [Number(this.#negLength - counter), ...this.#indices[numValue * -1]] : - this.#indices[numValue * -1] = [Number(this.#negLength - counter)]; - - counter++; - })(); - })(); - else if (this.#neg[numValue] > 0) - (() => { - this.#array[this.#negLength - counter] = Number(numValue) * -1; - - this.#indices[numValue * -1] ? - this.#indices[numValue * -1] = [Number(this.#negLength - counter), ...this.#indices[numValue * -1]] : - this.#indices[numValue * -1] = [Number(this.#negLength - counter)]; - - counter++; - })(); - else continue; - } - })(); - })(); - - - (Object.keys(this.#pos).length) && - (() => { - const negLength = this.#negLength; - - for (const numValue in this.#pos) { - isNaN(numValue) && (() => false)(); - - if (this.#pos[numValue] > 1) (() => { - for (let i = 0; i < this.#pos[numValue]; i++) (() => { - this.#array[this.#negLength] = Number(numValue); - - this.#indices[numValue] ? - this.#indices[numValue][this.#indices[numValue].length] = (Number(this.#negLength)) : - this.#indices[numValue] = [Number(this.#negLength)]; - - this.#negLength++; - })(); - })(); - else if (this.#pos[numValue] > 0) (() => { - this.#array[this.#negLength] = Number(numValue); - - this.#indices[numValue] ? - this.#indices[numValue][this.#indices[numValue].length] = (Number(this.#negLength)) : - this.#indices[numValue] = [Number(this.#negLength)]; - - this.#negLength++; - })(); - else continue; + this.#array = []; + if (this.#negLength) { + let tempNegLength = this.#negLength; + for (const numValue in this.#neg) { + if (isNaN(numValue)) continue; + const num = Number(numValue) * -1, negOc = this.#neg[numValue]; + tempNegLength -= negOc; + this.#neg[numValue][0] = tempNegLength; + if (this.#neg[numValue][1] > 1) { + let i = 0; + for (i; i < this.#neg[numValue][1]; i++) + this.#array[this.#negLength - counter] = num, + counter++; } + else if (this.#neg[numValue][1] == 1) + this.#array[this.#negLength - counter] = num, + counter++; + else continue; + } + } - this.#negLength = negLength; - })(); + if (Object.keys(this.#pos).length) { + let posPosition = this.#negLength; + let a = 0; + for (const numValue in this.#pos) { + a++; + if (isNaN(numValue)) continue; + const num = Number(numValue); + this.#pos[numValue][0] = posPosition; + if (this.#pos[numValue][1] > 1) { + let i = 0; + for (i; i < this.#pos[numValue][1]; i++) + this.#array[posPosition] = num, + posPosition++; + } + else if (this.#pos[numValue][1] == 1) { + this.#array[posPosition] = num, + posPosition++; + } + else continue; + } + } }; #insert (integer) { - (!integer || integer == null || integer == undefined || isNaN(integer) || integer === '') && (() => false)(); - integer < 0 ? - (() => { - integer *= -1; - this.#neg[integer] ? - this.#neg[integer]++ : - this.#neg[integer] = 1; - + if (!integer || + integer == null || + integer == undefined || + isNaN(integer) || + integer === '') return false; + if (integer < 0) + integer *= -1, + this.#neg[integer]?.[1] ? + this.#neg[integer][1]++ : + this.#neg[integer] = [null, 1], this.#negLength++; - })() : - this.#pos[integer] ? - this.#pos[integer]++ : - this.#pos[integer] = 1; - - this.#arrange(); + else + this.#pos[integer]?.[1] ? + this.#pos[integer][1]++ : + this.#pos[integer] = [null, 1]; return; } #insertArray (integers) { - (integers == null || integers == undefined || integers.length == 0 || !Array.isArray(integers)) && (() => false)(); - for (let index = 0; index < integers.length; index++) { - if (Array.isArray(integers[index])) { - this.#insertArray(integers[index]); - continue; - } + if (integers == null || + integers == undefined || + !integers.length || + !Array.isArray(integers)) return false; - if (integers[index] == null) continue; - if (isNaN(integers[index])) continue; - if (integers[index] === '') continue; - - let element = Number(integers[index]); - element < 0 ? - (() => { - element *= -1; - this.#neg[element] ? - this.#neg[element]++ : - this.#neg[element] = 1; - - this.#negLength++; - })() : - this.#pos[element] ? - this.#pos[element]++ : - this.#pos[element] = 1; - }; - this.#arrange(); + let index = 0; + for (index; index < integers.length; index++) { + let element = integers[index]; + Array.isArray(element) ? + this.#insertArray(element) : + this.#insert(element); + } return; } + #enforceRemove (integer = null, ...integers) { + if (integers) { + let i = 0; + for (i; i < integers.length; i++) + this.#enforceRemove(integers[i]); + } + if (Array.isArray(integer)) { + let i = 0; + for (i; i < integer.length; i++) + this.#enforceRemove(integer[i]); + } + else if (this.search(integer)[1]) { + if (Number(integer) < 0) + this.#neg[Number(integer * -1)][1]--, + this.#negLength--; + else + this.#pos[Number(integer)][1]--; + this.#arrange(); + } + return; + } + + #enforceRemoveAll (integer = null, ...integers) { + if (integers) { + let i = 0; + for (i; i < integers.length; i++) + this.#enforceRemoveAll(integers[i]); + } + if (Array.isArray(integer)) { + let i = 0; + for (i; i < integer.length; i++) + this.#enforceRemoveAll(integer[i]); + } + else if (this.search(integer)[1]) { + if (Number(integer) < 0) + this.#negLength -= this.#neg[Number(integer * -1)][1], + this.#neg[Number(integer * -1)][1] = 0; + else + this.#pos[Number(integer)][1] = 0; + this.#arrange(); + } + return; + } + /** - * Adds the given arguments to the AroTable. its arguments could be an integer or multiple integers could be passed, or an array, or better still a combination of both. Returns true if successful, returns false if not. + * Adds the given arguments to the AroTable. Its arguments could be an integer or multiple integers could be passed, or an array, or better still a combination of both. Returns true if successful, returns false if not. * @param data * @param values */ add (data = null, ...values) { const previousLength = this.#array.length; - values ? - this.#insertArray(values) : false; + values && + this.#insertArray(values); Array.isArray(data) ? - this.#insertArray(data) : data ? this.#insert(data) : false; + this.#insertArray(data) : data && this.#insert(data); + + this.#arrange(); - return previousLength == this.#array.length ? false : true; + return previousLength != this.#array.length; } /** - * Searches for an occurrence of the given value in the AroTable. Returns the indices of each occurrence if found, if not returns false. - * @param {Number} value + * Searches for an occurrence of the given integer in the AroTable. Returns an array with two values, the first is the first index the integer occurred in the AroTable, and the second shows how many times it occurred. If no occurrence is found, returns false. + * @param integer * @returns {Array} array */ - search (value) { - (value == null || value == undefined || isNaN(value)) && (() => false)(); - return this.#indices[Number(value)] ? this.#indices[Number(value)] : false; + search (integer) { + if (integer == null || + integer == undefined || + isNaN(integer)) return false; + return integer < 1 ? this.#neg[integer * -1]?.[0] == null || + this.#neg[integer * -1]?.[0] == undefined ? false : this.#neg[integer * -1] : this.#pos[integer]?.[0] == null || + this.#pos[integer]?.[0] == undefined ? false : this.#pos[integer]; } /** - * Deletes the first occurrence of the integer from the AroTable. Returns true if successful, returns false if not. - * @param {Number} integer + * Deletes the first occurrence of the given argument(s) from the AroTable. Its arguments could be an integer or multiple integers could be passed, or an array, or better still a combination of both. Returns true if successful, returns false if not. + * @param integer + * @param integers */ - remove (integer) { - return this.search(integer) !== false ? - ((() => { - Number(integer) < 0 ? - (() => { - this.#neg[Number(integer * -1)]--; - this.#negLength--; - })() : - this.#pos[Number(integer)]--; - this.#arrange(); - return true; - }))() : - (() => false)(); + remove (integer = null, ...integers) { + const previousLength = this.#array.length; + this.#enforceRemove(integer, ...integers); + return previousLength != this.#array.length; } /** - * Deletes all occurrences of the integer from the AroTable. Returns true if successful, returns false if not. - * @param {Number} integer + * Deletes all occurrences of the given argument(s) from the AroTable. Its arguments could be an integer or multiple integers could be passed, or an array, or better still a combination of both. Returns true if successful, returns false if not. + * @param integer + * @param integers */ - removeAll (integer) { - return this.search(integer) !== false ? - ((() => { - Number(integer) < 0 ? - (() => { - this.#negLength -= this.#neg[Number(integer * -1)]; - this.#neg[Number(integer * -1)] = 0; - })() : - this.#pos[Number(integer)] = 0; - this.#arrange(); - return true; - }))() : - (() => false)(); + removeAll (integer = null, ...integers) { + const previousLength = this.#array.length; + this.#enforceRemoveAll(integer, ...integers); + return previousLength != this.#array.length; } /** * Returns true if the AroTable is empty, returns false if not. */ isEmpty () { - return this.#array.length == 0 ? true : false; + return !this.#array.length; } @@ -292,11 +253,10 @@ export default class AroTable { * Wipes the AroTable clean. */ empty () { - this.#pos = {}; - this.#neg = {}; - this.#negLength = 0; - this.#indices = {}; - this.#array = []; + this.#pos = {}, + this.#neg = {}, + this.#negLength = 0, + this.#array = []; } /** @@ -304,11 +264,9 @@ export default class AroTable { */ dropPositives () { const previousLength = this.#array.length; - - this.#pos = {}; - this.#arrange(); - - return previousLength == this.#array.length ? false : true; + this.#pos = {}, + this.#arrange(); + return previousLength != this.#array.length; } /** @@ -316,12 +274,10 @@ export default class AroTable { */ dropNegatives () { const previousLength = this.#array.length; - - this.#neg = {}; - this.#negLength = 0; - this.#arrange(); - - return previousLength == this.#array.length ? false : true; + this.#neg = {}, + this.#negLength = 0, + this.#arrange(); + return previousLength != this.#array.length; } /** @@ -330,25 +286,18 @@ export default class AroTable { dropUnits () { const previousLength = this.#array.length; - for (const intCount in this.#neg) (() => { - this.#neg[intCount] == 1 ? - (() => { - this.#negLength -= this.#neg[intCount]; - this.#neg[intCount] = 0; - })() - : - false; - })(); + for (const intCount in this.#neg) + if (this.#neg[intCount][1] == 1) + this.#negLength -= this.#neg[intCount][1], + this.#neg[intCount][1] = 0; - for (const intCount in this.#pos) (() => { - this.#pos[intCount] == 1 ? - this.#pos[intCount] = 0 : - false; - })(); + for (const intCount in this.#pos) + if (this.#pos[intCount][1] == 1) + this.#pos[intCount][1] = 0; this.#arrange(); - return previousLength == this.#array.length ? false : true; + return previousLength != this.#array.length; } /** @@ -357,25 +306,18 @@ export default class AroTable { dropDuplicates () { const previousLength = this.#array.length; - for (const intCount in this.#neg) (() => { - this.#neg[intCount] > 1 ? - (() => { - this.#negLength -= this.#neg[intCount]; - this.#neg[intCount] = 0; - })() - : - false; - })(); + for (const intCount in this.#neg) + if (this.#neg[intCount][1] > 1) + this.#negLength -= this.#neg[intCount][1], + this.#neg[intCount][1] = 0; - for (const intCount in this.#pos) (() => { - this.#pos[intCount] > 1 ? - this.#pos[intCount] = 0 : - false; - })(); + for (const intCount in this.#pos) + if (this.#pos[intCount][1] > 1) + this.#pos[intCount][1] = 0; this.#arrange(); - return previousLength == this.#array.length ? false : true; + return previousLength != this.#array.length; } /** @@ -384,25 +326,18 @@ export default class AroTable { clearDuplicates () { const previousLength = this.#array.length; - for (const intCount in this.#neg) (() => { - this.#neg[intCount] > 0 ? - (() => { - this.#negLength -= (this.#neg[intCount] - 1); - this.#neg[intCount] = 1; - })() - : - false; - })(); + for (const intCount in this.#neg) + if (this.#neg[intCount][1] > 0) + this.#negLength -= (this.#neg[intCount][1] - 1), + this.#neg[intCount][1] = 1; - for (const intCount in this.#pos) (() => { - this.#pos[intCount] > 0 ? - this.#pos[intCount] = 1 - : false; - })(); + for (const intCount in this.#pos) + if (this.#pos[intCount][1] > 0) + this.#pos[intCount][1] = 1; this.#arrange(); - return previousLength == this.#array.length ? false : true; + return previousLength != this.#array.length; } @@ -411,27 +346,19 @@ export default class AroTable { * @returns {Array} array */ returnDuplicates () { - let duplicates = []; + const duplicates = []; let index = 0; - for (const int in this.#neg) (() => { - this.#neg[int] > 1 ? - (() => { - duplicates[index] = Number(int * -1); + for (const int in this.#neg) + if (this.#neg[int][1] > 1) + duplicates[index][1] = Number(int * -1), index++; - })() : - false; - })(); - - for (const int in this.#pos) (() => { - this.#pos[int] > 1 ? - (() => { - duplicates[index] = Number(int); + + for (const int in this.#pos) + if (this.#pos[int][1] > 1) + duplicates[index][1] = Number(int), index++; - })() : - false; - })(); - return duplicates.length > 0 ? this.#aroSort(duplicates) : false; + return duplicates.length > 0 ? this.#mergeSort(duplicates) : false; } /** @@ -439,27 +366,19 @@ export default class AroTable { * @returns {Array} array */ returnUnits () { - let units = []; + const units = []; let index = 0; - for (const int in this.#neg) (() => { - this.#neg[int] == 1 ? - (() => { - units[index] = Number(int * -1); + for (const int in this.#neg) + if (this.#neg[int][1] == 1) + units[index][1] = Number(int * -1), index++; - })() : - false; - })(); - - for (const int in this.#pos) (() => { - this.#pos[int] == 1 ? - (() => { - units[index] = Number(int); + + for (const int in this.#pos) + if (this.#pos[int][1] == 1) + units[index][1] = Number(int), index++; - })() : - false; - })(); - return units.length > 0 ? this.#aroSort(units) : false; + return units.length > 0 ? this.#mergeSort(units) : false; } /** @@ -469,16 +388,12 @@ export default class AroTable { returnNegatives () { const negatives = []; let index = 0; - for (const neg in this.#neg) { - if (this.#neg[neg] != 0) { - negatives[index] = Number(neg * -1); - index++; - } else { - continue; - } - } + for (const neg in this.#neg) + if (this.#neg[neg][1] != 0) + negatives[index][1] = Number(neg * -1), + index++; - return negatives.length > 0 ? this.#aroSort(negatives) : false; + return negatives.length > 0 ? this.#mergeSort(negatives) : false; } /** @@ -488,16 +403,12 @@ export default class AroTable { returnPositives () { const positives = []; let index = 0; - for (const pos in this.#pos) { - if (this.#pos[pos] != 0) { - positives[index] = Number(pos); - index++; - } else { - continue; - } - } + for (const pos in this.#pos) + if (this.#pos[pos][1] != 0) + positives[index][1] = Number(pos), + index++; - return positives.length > 0 ? this.#aroSort(positives) : false; + return positives.length > 0 ? this.#mergeSort(positives) : false; } /** @@ -522,8 +433,7 @@ export default class AroTable { */ getDistribution () { return { - 'Positive Integers': - Number(this.#array.length - this.#negLength), + 'Positive Integers': Number(this.#array.length - this.#negLength), 'Negative Integers': Number(this.#negLength) }; } diff --git a/README.md b/README.md index be28f64..9c61f13 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ aroTable.add(1,'-2','three',-4,'5',null,7,undefined,'nine'); // returns true ### The **remove()** Method -The **remove()** method takes in an integer argument and removes an occurrence of the integer from the AroTable. Returns true if successful, returns false if not: +The **remove()** method takes the same kind of arguments as the [add()](#the-add-method) method and then removes an occurrence of any value—that exists in the AroTable—passed as an argument from the AroTable. Returns true if successful, returns false if not: ```js const aroTable = new AroTable(2); @@ -149,9 +149,11 @@ aroTable.remove(1); // Returns false aroTable.remove(2); // Returns true ``` +The **remove()** method can also work with strings that can be converted to a valid integer, with the exception of **null** and empty string (**''**). See the [add()](#the-add-method) method for examples. + ### The **removeAll()** Method -The **removeAll()** method takes in an integer argument and removes all occurrences of the integer from the AroTable. Returns true if successful, returns false if not: +The **removeAll()** method takes the same kind of arguments as the [add()](#the-add-method) method and removes all occurrences of any value—that exists in the AroTable—passed as an argument from the AroTable. Returns true if successful, returns false if not: ```js const aroTable = new AroTable(2,2,2,4,5,6,2); @@ -161,15 +163,17 @@ aroTable.removeAll('2'); // Returns true aroTable.returnArray(); // Returns [4, 5, 6] ``` +The **removeAll()** method can also work with strings that can be converted to a valid integer, with the exception of **null** and empty string (**''**). See the [add()](#the-add-method) method for examples. + ### The **search()** Method -The **search()** method takes in an integer argument and returns the indices that that integer would appear in an array representation, returns false if no occurrence is found: +The **search()** method takes in an integer argument. Returns an array with two values, the first is the first index the integer occurs in an array representation of the AroTable, and the second shows how many times it occurred. If no occurrence is found, returns false. ```js const aroTable = new AroTable(1,3,-2,5,6,-2,6,7,3); -aroTable.search(-2); // Returns [0, 1] -aroTable.search(3); // Returns [3, 4] +aroTable.search(-2); // Returns [ 0, 2 ] +aroTable.search(3); // Returns [ 3, 1 ] aroTable.search(9); // Returns false ``` @@ -188,7 +192,7 @@ aroTable.returnArray(); // Returns [ 1, 2, 3, 4, 5, 6 ] ### The **returnDuplicates()** Method -The **returnDuplicates()** method returns a sorted array of all integers with duplicated occurrences in the AroTable, if none exists, returns false: +The **returnDuplicates()** method returns a sorted array (using Merge Sort) of all integers with duplicated occurrences in the AroTable, if none exists, returns false: ```js const aroTable = new AroTable(1,2,3,4,2,3,4,5,6,6,6,3); @@ -224,7 +228,7 @@ aroTable.dropUnits(); // Returns false ### The **returnUnits()** Method -The **returnUnits()** method returns a sorted array of all integers with a single occurrence in the AroTable, if none exists, returns false: +The **returnUnits()** method returns a sorted array (using Merge Sort) of all integers with a single occurrence in the AroTable, if none exists, returns false: ```js const aroTable = new AroTable(1,2,3,4,2,3,4,5,6,6,6,3); @@ -248,7 +252,7 @@ aroTable.dropPositives(); // Returns false ### The **returnPositives()** Method -The **returnPositives()** method returns a sorted array of all positive integers in the AroTable, if none exists returns false: +The **returnPositives()** method returns a sorted array (using Merge Sort) of all positive integers in the AroTable, if none exists returns false: ```js const aroTable = new AroTable(-5,-4,-3,'-2',-1,'0',1,2,'3',4,5); @@ -272,7 +276,7 @@ aroTable.dropNegatives(); // Returns false ### The **returnNegatives()** Method -The **returnNegatives()** method returns a sorted array of all negative integers in the AroTable, if none exists returns false: +The **returnNegatives()** method returns a sorted array (using Merge Sort) of all negative integers in the AroTable, if none exists returns false: ```js const aroTable = new AroTable(-5,-4,-3,'-2',-1,'0',1,2,'3',4,5); diff --git a/package.json b/package.json index 4a9be29..72efbeb 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,7 @@ "type": "module", "repository": { "type": "git", - "url": "git://github.com/Aro1914/AroTable.git" - }, - "bugs": { - "url": "https://github.com/Aro1914/AroTable/issues" + "url": "git://github.com/Aro1914/AroTable.git/issues" }, "homepage": "https://github.com/Aro1914/AroTable#readme" -} +} \ No newline at end of file