utilities/index.js
2020-06-29 14:25:03 +02:00

137 lines
2.9 KiB
JavaScript

/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of utilities which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, May 2020
*/
'use strict';
/**
* truncates a floating point number
*
* @param {number} num number to truncate
* @param {number} len length to truncate to
* @returns {number} truncated number
*/
function truncate_decimal (num, len) {
return Math.round (num * (10 ** len)) / (10 ** len);
}
/**
* parse json and catch invalid strings
*
* @param {string} text input
* @returns {any} parsed
*/
function try_parse_json (text) {
try {
return JSON.parse (text);
}
catch (e) {
// noop
}
return null;
}
/**
* copy an object to prevent modification to the original
*
* @param {object} obj object to copy
* @returns {object} copy
*/
function copy_object (obj) {
return JSON.parse (JSON.stringify (obj));
}
/**
* run a regular expression and callback for every result
*
* @param {any} regex regular expression
* @param {any} data data to run on
* @param {any} func function to execute
*/
function run_regex (regex, data, func) {
if (!regex.global) {
const result = regex.exec (data);
if (result)
func (result);
return;
}
let res = regex.exec (data);
while (res) {
func (res);
res = regex.exec (data);
}
}
/**
* check if an object is either undefined, null or NaN
*
* @param {any} obj object to check
* @returns {boolean} true if nil
*/
function is_nil (obj) {
return typeof obj === 'undefined'
|| obj === null
|| (typeof obj === 'number' && isNaN (obj));
}
function to_search_string (element, field) {
return Array.isArray (field)
? field.map ((f) => element[f])
.filter ((v) => typeof v !== 'undefined')
.join (' ')
: element[field];
}
/**
* filter nested objects
*
* @param {Array<object>} input
* @param {Array<{field: string, filter: RegExp}>} filters
* @returns {Array<object>} filtered data
*/
function recursive_filter (input, filters, children_key = 'children') {
const data = [ ...input ];
const filtered = [];
for (let i = 0; i < data.length; i++) {
const e = { ...data[i] };
data[i] = e;
let match = true;
for (const filter of filters) {
const search_str = to_search_string (e, filter.field);
if (!filter.filter.test (search_str)) {
match = false;
break;
}
}
if (match) {
filtered.push (e);
}
else {
if (typeof e[children_key] === 'undefined')
continue;
e[children_key] = recursive_filter (
e[children_key],
filters,
children_key
);
if (e[children_key].length > 0)
filtered.push (e);
}
}
return filtered;
}
module.exports = {
truncate_decimal,
try_parse_json,
copy_object,
run_regex,
is_nil,
recursive_filter
};