nope-js-node
Version:
NoPE Runtime for Nodejs. For Browser-Support please use nope-browser
407 lines (406 loc) • 11.8 kB
JavaScript
;
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.maxOfArray = exports.minOfArray = exports.avgOfArray = exports.zipArrays = exports.elementInArray = exports.flattenDeep = exports.countElements = exports.limitedPush = exports.arraysEqual = exports.getElement = exports.toSet = exports.extractListElement = exports.dynamicSort = void 0;
const objectMethods_1 = require("./objectMethods");
/**
* Sorts a List based on the given property
* Usage :
* ```javascript
* a = [{a : 1, b: 2}, {a : 2, b: 1}];
* b = a.sort(dynamicSort('b'))
* b => [{a : 2, b: 1}, {a : 1, b: 2}]
* ```
* @export
* @param {string} _property Property Name / Path to Sort the List
* @returns
*/
function dynamicSort(_property, reverse = false) {
const _sortOrder = reverse ? -1 : 1;
return function (a, b) {
const _a = (0, objectMethods_1.rgetattr)(a, _property);
const _b = (0, objectMethods_1.rgetattr)(b, _property);
if (typeof _a === "number" && typeof _b === "number") {
const result = _a < _b ? -1 : _a > _b ? 1 : 0;
return result * _sortOrder;
}
else if (typeof _a === "number") {
return 1 * _sortOrder;
}
else if (typeof _b === "number") {
return -1 * _sortOrder;
}
else if (typeof _a === "string" && typeof _b === "string") {
return _a < _b ? -1 : _a > _b ? 1 : 0;
}
return 0;
};
}
exports.dynamicSort = dynamicSort;
/**
* Extracts the Data of the given List
*
* # Example:
*
* ```javascript
* const list = [{"id":1, "data":"a"},{"id":2, "data":"b"}]
* const res = extractListElement(list, "data") // => ["a","b"]
* ```
*
* @export
* @param {Array<any>} list List, where data should be extracted
* @param {string} path path pointing to the Data in the List
* @returns {Array<any>} List only containing the Elements.
*/
function extractListElement(list, path) {
// Define Function to extract the Properties.
function _extract(_property) {
const _ret = (0, objectMethods_1.rgetattr)(_property, path);
/** Returns the Value if it is in the Element */
if (_ret) {
return _ret;
}
}
return list.map(_extract);
}
exports.extractListElement = extractListElement;
/**
* Converts a List to Set.
*
* @export
* @template T
* @param {Array<T>} list The list as input
* @returns {Set<T>} The Set
*/
function toSet(list) {
const _ret = new Set();
for (const item of list) {
_ret.add(item);
}
return _ret;
}
exports.toSet = toSet;
/**
* Extracts the first Element if Possible, which includes the Operand
*
* # Example
*
* ```javascript
* const a = [{path:'hallo'}, {path:'hallo2'}]
* const res = getElement(a, 'hallo2', 'path') // => {path:'hallo2'}
* ```
*
* @export
* @template T
* @param {Array<T>} list The list which is considered
* @param {*} operand The Element which should looked for
* @param {string} [path=''] The where the Element should be found
* @returns {(T | null)}
*/
function getElement(list, operand, path = "") {
/** Iterate through the List an get the requested Element if possible */
for (const _element of list) {
/** Compare the Requested value with the value of the List-Item */
if (operand === (0, objectMethods_1.rgetattr)(_element, path)) {
return _element;
}
}
return null;
}
exports.getElement = getElement;
/**
* Function that will compare two arrays, if they are equal.
*
* # Example:
*
* ```javascript
* const a = [1,2,3,4,5]
* arraysEqual(a, [1,2,3,4]) // => false;
* arraysEqual(a, [1,2,3,4,5]) // => true;
* arraysEqual(a, [1,2,3,5,4], false) // => true;
* ```
*
* @param a Array Element A
* @param b Array Element B
* @param considerOrder Flag to enable/disable Order checking
*/
function arraysEqual(a, b, considerOrder = true) {
if (a === b)
return true;
if (a == null || b == null)
return false;
if (a.length != b.length)
return false;
let _a = a;
let _b = b;
if (!considerOrder) {
_a = a.concat().sort();
_b = b.concat().sort();
}
for (let i = 0; i < _a.length; ++i) {
if (_a[i] !== _b[i])
return false;
}
return true;
}
exports.arraysEqual = arraysEqual;
/**
* Function which will limit the Amount of Element stored in the Array during
* pushing a new Element. If the Maximum is exited the Elementes will be removed
* with the FIFO Principal.
*
* # Example 1:
*
* In this example the limit will be reached.
*
* ```javascript
* const a = [1,2,3,4,5]
* limitedPush(a, 6,5) // => [2,3,4,5,6];
* ```
* # Example 2:
*
* The limit wont be excided
*
* ```javascript
* const a = [1,2,3,4,5]
* limitedPush(a, 6, 10) // => [1,2,3,4,5,6];
* ```
* @param array The considered Array
* @param element The Element which should be added
* @param maxElements The Max. Amount of Elements, which are allowed to store.
*/
function limitedPush(array, element, maxElements) {
array.push(element);
if (array.length > maxElements) {
array.splice(0, 1);
}
}
exports.limitedPush = limitedPush;
/**
* Function to count the Number of Element in an Array. A Dict with the Elements
* as string will be returned.
*
* # Example:
*
* ```javascript
* const a = [1,2,3,4,5,5,5]
* countElements(a) // => Map<{1:1, 2:1,3:1,4:1,5:3}>;
* ```
* @param array The Array
*/
function countElements(array) {
const ret = new Map();
for (const element of array) {
ret.set(element, (ret.get(element) || 0) + 1);
}
return ret;
}
exports.countElements = countElements;
/**
* Function, which will Flatten the Array.
*
* # Example:
*
* ```javascript
* const a = [1,[2,[3,[4,[5]]]]]
* flattenDeep(a) // => [1,2,3,4,5]
* ```
* @param arrayToFlatten The Array
*/
function flattenDeep(arrayToFlatten) {
return arrayToFlatten.reduce((acc, val) => {
return Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val);
}, []);
}
exports.flattenDeep = flattenDeep;
/**
* Function, to Test whether the Element is present in the Array
*
* # Example 1:
*
* ```javascript
* const list = [{"id":1, "data":"a"},{"id":2, "data":"b"},{"id":3, "data":"c"}]
* elementInArray("b", list, "data") // => true
* elementInArray(5, list, "data") // => false
* elementInArray("b", list, "property_not_in_data") // => false
* ```
*
* # Example 2:
*
* ```javascript
* const list = [{"id":1, "data":["a"]},{"id":2, "data":["b"]},{"id":3, "data":["c"]}]
* elementInArray("b", list, "data/0") // => true
* elementInArray("d", list, "data/0") // => false
* elementInArray("b", list, "data") // => false <- Path doesnt contain 'b'
* elementInArray("b", list, "data/1") // => false <- Path wrong, no elements there
* ```
* @param objToTest The Object to Test
* @param array The array to consider
* @param path The path, under which the element will be found
*/
function elementInArray(objToTest, array, path) {
const testData = (0, objectMethods_1.rgetattr)(objToTest, path, false);
for (const [idx, element] of array.entries()) {
if (testData === (0, objectMethods_1.rgetattr)(element, path, true)) {
return idx;
}
}
return -1;
}
exports.elementInArray = elementInArray;
/**
* Function to ZIP to Arrays.
*
* # Example 1:
*
* ```javascript
* const a = [1,2,3,4]
* const b = ["a","b","c","d"]
* zipArrays(a,b) // => [(1,"a"), (2, "b"), ...]
* ```
* @param arr1
* @param arr2
*/
function zipArrays(arr1, arr2) {
if (arr1.length !== arr2.length) {
throw Error("Length of the Elements doesnt match!");
}
const res = arr1.map(function (e, i) {
return [e, arr2[i]];
});
return res;
}
exports.zipArrays = zipArrays;
/**
* Helper to determine the average of an array
*
* # Example 1:
*
* ```javascript
* const a = [1,2,3,4]
* // default behavior:
* avgOfArray(a,"") // => 2.5
* // if no data present at the path the default value is used:
* avgOfArray(a,"a",1) // => 1
* ```
*
* # Example 2:
*
* ```javascript
* const a = [{value:1},{value:2},{value:3},{value:4}]
* // default behavior:
* avgOfArray(a,"value") // => 2.5
* // if no data present at the path the default value is used:
* avgOfArray(a,"a",1) // => 1
* ```
* @author M.Karkowski
* @export
* @param {any[]} arr The array
* @param {string} path The path to the data.
* @param {number} [defaultValue=0] if no data present at the path the default value is used.
* @return {*} {number}
*/
function avgOfArray(arr, path, defaultValue = 0) {
if (arr.length === 0) {
return defaultValue;
}
const arrOfValues = arr.map((item) => {
return (0, objectMethods_1.rgetattr)(item, path, defaultValue);
});
const added = arrOfValues.reduce((prev, curr) => {
return prev + curr;
});
return added / arr.length;
}
exports.avgOfArray = avgOfArray;
/**
* Helper to determine the minimum of an array
*
* # Example 1:
*
* ```javascript
* const a = [1,2,3,4]
* // default behavior:
* minOfArray(a,"") // => 1
* // if no data present at the path the default value is used:
* minOfArray(a,"a",1) // => 1
* ```
*
* # Example 2:
*
* ```javascript
* const a = [{value:1},{value:2},{value:3},{value:4}]
* // default behavior:
* minOfArray(a,"value") // => 1
* // if no data present at the path the default value is used:
* minOfArray(a,"a",1) // => 1
* ```
* @param {any[]} arr The array
* @param {string} path The path to the data.
* @param {number} [defaultValue=0] if no data present at the path the default value is used.
* @returns
*/
function minOfArray(arr, path, defaultValue = 0) {
if (arr.length === 0) {
return {
min: defaultValue,
index: -1,
};
}
const arrOfValues = arr.map((item) => {
return (0, objectMethods_1.rgetattr)(item, path, defaultValue);
});
const min = Math.min(...arrOfValues);
return {
min,
index: arrOfValues.indexOf(min),
};
}
exports.minOfArray = minOfArray;
/**
* Helper to determine the maximum of an array
*
* # Example 1:
*
* ```javascript
* const a = [1,2,3,4]
* // default behavior:
* maxOfArray(a,"") // => 4
* // if no data present at the path the default value is used:
* maxOfArray(a,"a",1) // => 1
* ```
*
* # Example 2:
*
* ```javascript
* const a = [{value:1},{value:2},{value:3},{value:4}]
* // default behavior:
* maxOfArray(a,"value") // => 4
* // if no data present at the path the default value is used:
* maxOfArray(a,"a",1) // => 1
* ```
* @param {any[]} arr The array
* @param {string} path The path to the data.
* @param {number} [defaultValue=0] if no data present at the path the default value is used.
* @returns
*/
function maxOfArray(arr, path, defaultValue = 0) {
if (arr.length === 0) {
return {
max: defaultValue,
index: -1,
};
}
const arrOfValues = arr.map((item) => {
return (0, objectMethods_1.rgetattr)(item, path, defaultValue);
});
const max = Math.max(...arrOfValues);
return {
max: max,
index: arrOfValues.indexOf(max),
};
}
exports.maxOfArray = maxOfArray;