same.js
Version:
A Class of Parallel Arrays Manipulation
451 lines (404 loc) • 16.9 kB
JavaScript
'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,
};