UNPKG

same.js

Version:

A Class of Parallel Arrays Manipulation

451 lines (404 loc) 16.9 kB
'use strict'; const { MissingValue, MissingFn, IncorrectValue } = require("./Err/err.js"); const { charNumber } = require("./utils/charNumber.js"); /** * The Same in its insides */ class Same { constructor() { this.first = []; this.second = []; this.timestamp = new Date(); } /** * Inserts in the Same two values * @param {any} [firstValue] The value stored in the first array of the Same * @param {any} [secondValue] The value stored in the second array of the Same * @returns {number} The new Same length */ insert(firstValue, secondValue) { this.first.push(firstValue); this.second.push(secondValue); if (typeof (firstValue) == "object" && typeof (secondValue) == "object") { let i = 0; Object.values(firstValue).forEach((element) => { this.first.push(Object.values(firstValue)[i]); this.second.push(Object.values(secondValue)[i]); if (Array.isArray(Object.values(firstValue)[i]) && Array.isArray(Object.values(secondValue)[i])) { for (let element of Object.values(firstValue)[i]) { this.first.push(element); } for (let element of Object.values(secondValue)[i]) { this.second.push(element); } } if (this.first.length > this.second.length) { let lg = this.first.length; for (let i = this.second.length; i < lg; i++) { this.first.push(undefined); } } else if (this.first.length < this.second.length) { let lg = this.second.length; for (let i = this.first.length; i < lg; i++) { this.second.push(undefined); } } i++ }); } else if (Array.isArray(firstValue) && Array.isArray(secondValue)) { for (let element of firstValue) { this.first.push(element); } for (let element of secondValue) { this.second.push(element); } } if (this.first.length > this.second.length) { let lg = this.first.length; for (let i = this.second.length; i < lg; i++) { this.first.push(undefined); } } else if (this.first.length < this.second.length) { let lg = this.second.length; for (let i = this.first.length; i < lg; i++) { this.second.push(undefined); } } return this.first.length; } /** * Overwrites the value into the corresponding one; if there are more indexes with the same value, it returns an array of its overwritten values * @param {any} [value] The value in the same index of its correspoding * @returns {any} The corresponding value of the first parameter */ over(value) { var toOverFirst; var toOverSecond; var i = 0 var indexes = []; while (i < this.first.length) { toOverFirst = this.first.indexOf(value, i); toOverSecond = this.second.indexOf(value, i); if (toOverSecond > toOverFirst) { if (toOverFirst != -1) { i = toOverFirst; indexes.push({ arrIndex: i, arrayN: 1 }); i = toOverFirst + 1; } else { i = toOverSecond; indexes.push({ arrIndex: i, arrayN: 2 }); i = toOverSecond + 1; } } else if (toOverFirst > toOverSecond) { if (toOverSecond != -1) { i = toOverSecond; indexes.push({ arrIndex: i, arrayN: 2 }); i = toOverSecond + 1; } else { i = toOverFirst; indexes.push({ arrIndex: i, arrayN: 1 }); i = toOverFirst + 1; } } else if (toOverFirst == toOverSecond) { if (toOverFirst != -1) { i = toOverFirst; indexes.push({ arrIndex: i, arrayN: 3 }); } i++; } } if (indexes.length == 1) { toOverFirst = this.first.indexOf(value); toOverSecond = this.second.indexOf(value); } else { let over = []; indexes.forEach(element => { if (element.arrayN == 1) { over.push(this.second[element.arrIndex]); } else if (element.arrayN == 2) { over.push(this.first[element.arrIndex]); } }) return over; } if (toOverFirst == -1 && toOverSecond == -1) { try { NoValue() } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } if (toOverSecond == -1) { let over = this.second[toOverFirst]; return over; } if (toOverFirst == -1) { let over = this.first[toOverSecond]; return over; } } /** * Loops thorught every element in the Same and checks if there's the value to search for * @param {any} [value] The value to check * @returns {boolean | object | object[]} If the value is not in the same returns false, else returns one or more objects containing infos about the position of the value found */ async has(value) { let i = 0; let index, nArray; let checks = []; await this.forEach((element) => { if (element == value) { index = i > this.first.length ? i - this.first.length : i; nArray = i > this.first.length ? 2 : 1; checks.push({ array: nArray, index: index }); } i++; }) if (checks.length == 0) return false; return checks; } /** * Replaces every undefined variable inside the Same (FROM THE FIRST ARRAY TO THE SECOND) * @param {any[]} [elements] The array of elements to replace in order * @returns {number} The new Same length */ async replaceUnd(elements = []) { let pos = await this.has(undefined); if (!Array.isArray(elements)) elements = [elements]; let i = 0 elements.forEach(element => { if (pos[i].array == 1) { this.first[pos[i].index] = element; } else if (pos[i].array == 2) { this.second[pos[i].index] = element; } i++ }) return this.first.length; } /** * Replaces the variables in the Same from the index * @param {number | any} [index] The index of the variables to replace (it can be one of the values itself) * @param {boolean} [isIndex] Checks if the number inserted as [index] is an index or a variable inside the Same * @param {any} [firstElement] The value to replace in the first array * @param {any} [secondElement] The value to replace in the second array * @returns {any[]} An array of the replaced elements */ replace(index, isIndex = true, firstElement, secondElement) { var toReplace1 = index; var toReplace2 = index; if (isNaN(index) || !isIndex) { toReplace1 = this.first.indexOf(index); toReplace2 = this.second.indexOf(index); } if(toReplace2 < toReplace1 && toReplace2 != -1) toReplace1 = toReplace2; else if(toReplace1 < toReplace2 && toReplace1 != -1) toReplace2 = toReplace1; let previous = [this.first[toReplace1 != -1 ? toReplace1 : toReplace2], this.second[toReplace2 != -1 ? toReplace2 : toReplace1]] if (toReplace2 == -1) { this.first[toReplace1] = firstElement; this.second[toReplace1] = secondElement; } else if (toReplace1 == -1) { this.first[toReplace2] = firstElement; this.second[toReplace2] = secondElement; } else { this.first[toReplace1] = firstElement; this.second[toReplace2] = secondElement; } return previous; } /** * Only returns an Object with an array of a part from the first and second arrays (DOES NOT DELETE THE ELEMENTS FROM THE SAME) * @param {number | any} firstIndex The index of the Same from where the selection starts (it may be the value of the index itself) * @param {number | any} lastIndex The index of the Same form where the selection ends (it may be the value of the index itself) * @returns {object} The container of the elements cut in the first and second array */ cut(firstIndex, lastIndex) { var _firstIndex = firstIndex; var _lastIndex = lastIndex; if (isNaN(firstIndex)) { _firstIndex = this.first.indexOf(firstIndex); if (_firstIndex == -1) _firstIndex = this.second.indexOf(firstIndex); } if (isNaN(lastIndex)) { _lastIndex = this.first.indexOf(lastIndex); if (_lastIndex == -1) _lastIndex = this.second.indexOf(lastIndex); } if (_firstIndex == -1 || _lastIndex == -1) { try { NoValue() } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } var firstElement = this.first.slice(_firstIndex, _lastIndex + 1); var secondElement = this.second.slice(_firstIndex, _lastIndex + 1); var portion = { firstElement: firstElement, secondElement: secondElement } return portion; } /** * removes one or more elements at the indexes * @param {number | any | any[]} [value] The index from where the selection starts; it can be the value of the index itself (not a number; it's alredy a index); if it's an array of values, 'spaces' can be omitted * @param {boolean} [isIndex] Decides if the value must be an index of the array or the value of an element (default: true -- has no effect if value is not a number or an array of numbers) * @param {number} [spaces] The number of indexes that will be removed after the first one (default: 1) * @returns {number} The new Same length */ remove(value, isIndex = true, spaces = 1) { if (isNaN(spaces)) { try { _0Value() } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } var toRemoveFirst = value; var toRemoveSecond = value; if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { let index; if (isNaN(value[i]) || isIndex == false) { toRemoveFirst = this.first.indexOf(value[i], 0); toRemoveSecond = this.second.indexOf(value[i], 0); if (toRemoveFirst != -1) { this.first.splice(toRemoveFirst, 1); this.second.splice(toRemoveFirst, 1); } else if (toRemoveSecond != 1) { this.first.splice(toRemoveSecond, 1); this.second.splice(toRemoveSecond, 1); } } else { if (this.second.indexOf(value[i]) == -1) { index = this.first.indexOf(value[i]); this.first.splice(index, 1); this.second.splice(index, 1); } else if (this.first.indexOf(value[i]) == -1) { index = this.second.indexOf(value[i]); this.first.splice(index, 1); this.second.splice(index, 1); } } } return this.first.length; } if (isNaN(value) || isIndex == false) { toRemoveFirst = this.first.indexOf(value, 0); toRemoveSecond = this.second.indexOf(value, 0); if (toRemoveFirst == -1 && toRemoveSecond == -1) { try { NoValue() } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } if (toRemoveSecond == -1) { this.first.splice(toRemoveFirst, spaces); this.second.splice(toRemoveFirst, spaces); } else if (toRemoveFirst == -1) { this.first.splice(toRemoveSecond, spaces); this.second.splice(toRemoveSecond, spaces); } return this.first.length; } this.first.splice(toRemoveFirst, spaces); this.second.splice(toRemoveSecond, spaces); return this.first.length; } /** * Reads how long is the first array of the Same * @returns {number} The Same length */ length() { return this.first.length; } /** * Executes a code for every elements inside the first array of the Same first, and then in the second one * @param {Function} [callback] The code that will be executed with every elements in the Same as parameter * @returns {undefined} Nothing. */ async forEach(callback = "funtion") { var element; if (typeof (callback == "function")) { for (let i = 0; i < this.first.length; i++) { element = this.first[i]; await callback(element); } for (let i = 0; i < this.second.length; i++) { element = this.second[i]; await callback(element); } return undefined; } else { try { NoFn() } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } } // inserts all numbers included in the two parameters in the first array, then tranlsate them in characters and pushes them in the second array; returns the new array length /** * Translates every number between the parameters (included) from decimal to spoken language and inserts the numbers in the first array, and the translations in the second one * @param {number} [from] The number from where the translation will start * @param {number} [to] The number from where the translation will end * @returns {number} The new Same length */ async charNumbInsert(from = 0, to = 0) { if (isNaN(from) || isNaN(to)) { try { _0Value(); } catch (err) { console.log(err.message + "\n" + err.name + "\n" + err.stack); } } else { var max, min; if (from != to) { max = from > to ? from : to; min = from < to ? from : to; } else { this.first.push(from); let updated = await charNumber(from); this.second.push(updated); return this.first.length; } for (let i = min; i <= max; i++) { this.first.push(i); let updated = await charNumber(i); this.second.push(updated); } return this.first.length; } } } /** * Generates and thorws an error where the value to overwrite was not in the Same */ function NoValue() { throw new MissingValue("\nNo such value in Same (check where the error was thrown at 6th Error line)"); } /** * Generates and throws an error where the argument was not a Function to execute */ function NoFn() { throw new MissingFn("\nArgument was not a Function (check where the error was thrown at 6th Error line)"); } /** * Generates and throws an error where the argument was not a Number */ function _0Value() { throw new IncorrectValue("\nArgument was not a Number (check where the error was thrown at 6th Error line)") } module.exports = { Same, NoValue, NoFn, _0Value, };