272 lines
7.3 KiB
JavaScript
272 lines
7.3 KiB
JavaScript
/**
|
|
* Applies a function to the value at the given index of an array
|
|
*
|
|
* @param index
|
|
* @param fn
|
|
* @param collection
|
|
* @returns Copy of the array with the element at the given index replaced with the result of the function application.
|
|
*/
|
|
const adjust = (index, fn, collection) => {
|
|
if (index >= 0 && index >= collection.length)
|
|
return collection;
|
|
if (index < 0 && Math.abs(index) > collection.length)
|
|
return collection;
|
|
const i = index < 0 ? collection.length + index : index;
|
|
return Object.assign([], collection, { [i]: fn(collection[i]) });
|
|
};
|
|
|
|
/* eslint-disable no-await-in-loop */
|
|
/**
|
|
* Performs right-to-left function composition with async functions support
|
|
*
|
|
* @param fns - Functions
|
|
* @returns Composed function
|
|
*/
|
|
const asyncCompose = (...fns) => async (value, ...args) => {
|
|
let result = value;
|
|
const reversedFns = fns.slice().reverse();
|
|
for (let i = 0; i < reversedFns.length; i += 1) {
|
|
const fn = reversedFns[i];
|
|
result = await fn(result, ...args);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Capitalize first letter of each word
|
|
*
|
|
* @param value - Any string
|
|
* @returns Capitalized string
|
|
*/
|
|
const capitalize = (value) => {
|
|
if (!value)
|
|
return value;
|
|
return value.replace(/(^|\s)\S/g, (l) => l.toUpperCase());
|
|
};
|
|
|
|
/**
|
|
* Casts value to array
|
|
*
|
|
* @template T - The type of the value.
|
|
* @param value - The value to cast into an array.
|
|
* @returns An array containing the given value.
|
|
*/
|
|
const castArray = (value) => {
|
|
return Array.isArray(value) ? value : [value];
|
|
};
|
|
|
|
/**
|
|
* Performs right-to-left function composition
|
|
*
|
|
* @param fns - Functions
|
|
* @returns Composed function
|
|
*/
|
|
const compose = (...fns) => (value, ...args) => {
|
|
let result = value;
|
|
const reversedFns = fns.slice().reverse();
|
|
for (let i = 0; i < reversedFns.length; i += 1) {
|
|
const fn = reversedFns[i];
|
|
result = fn(result, ...args);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Drops the last element from an array.
|
|
*
|
|
* @template T
|
|
* @param array - The array to drop the last element from
|
|
* @returns - The new array with the last element dropped
|
|
*/
|
|
const dropLast = (array) => array.slice(0, array.length - 1);
|
|
|
|
/**
|
|
* Applies a set of transformations to an object and returns a new object with the transformed values.
|
|
*
|
|
* @template T
|
|
* @param transformations - The transformations to apply.
|
|
* @param object - The object to transform.
|
|
* @returns The transformed object.
|
|
*/
|
|
function evolve(transformations, object) {
|
|
const result = {};
|
|
const keys = Object.keys(object);
|
|
for (let i = 0; i < keys.length; i += 1) {
|
|
const key = keys[i];
|
|
const transformation = transformations[key];
|
|
if (typeof transformation === 'function') {
|
|
result[key] = transformation(object[key]);
|
|
}
|
|
else {
|
|
result[key] = object[key];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is null or undefined.
|
|
*
|
|
* @template T - The type of the value.
|
|
* @param value - The value to check
|
|
* @returns True if the value is null or undefined, false otherwise
|
|
*/
|
|
const isNil = (value) => value === null || value === undefined;
|
|
|
|
/**
|
|
* Retrieves the value at a given path from an object.
|
|
*
|
|
* @param target - The object to retrieve the value from.
|
|
* @param path - The path of the value to retrieve.
|
|
* @param defaultValue - The default value to return if the path does not exist.
|
|
* @returns The value at the given path, or the default value if the path does not exist.
|
|
*/
|
|
const get = (target, path, defaultValue) => {
|
|
if (isNil(target))
|
|
return defaultValue;
|
|
const _path = castArray(path);
|
|
let result = target;
|
|
for (let i = 0; i < _path.length; i += 1) {
|
|
if (isNil(result))
|
|
return undefined;
|
|
result = result[_path[i]];
|
|
}
|
|
return isNil(result) ? defaultValue : result;
|
|
};
|
|
|
|
function last(value) {
|
|
return value === '' ? '' : value[value.length - 1];
|
|
}
|
|
|
|
/**
|
|
* Maps over the values of an object and applies a function to each value.
|
|
*
|
|
* @param object - The object to map over
|
|
* @param fn - The function to apply to each value
|
|
* @returns A new object with the mapped values
|
|
*/
|
|
const mapValues = (object, fn) => {
|
|
const entries = Object.entries(object);
|
|
const acc = {};
|
|
return entries.reduce((acc, [key, value], index) => {
|
|
acc[key] = fn(value, key, index);
|
|
return acc;
|
|
}, acc);
|
|
};
|
|
|
|
const isPercent = (value) => /((-)?\d+\.?\d*)%/g.exec(`${value}`);
|
|
/**
|
|
* Get percentage value of input
|
|
*
|
|
* @param value
|
|
* @returns Percent value (if matches)
|
|
*/
|
|
const matchPercent = (value) => {
|
|
const match = isPercent(value);
|
|
if (match) {
|
|
const f = parseFloat(match[1]);
|
|
const percent = f / 100;
|
|
return { percent, value: f };
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* Creates a new object by omitting specified keys from the original object.
|
|
*
|
|
* @param keys - The key or keys to omit
|
|
* @param object - The original object
|
|
* @returns The new object without the omitted keys
|
|
*/
|
|
const omit = (keys, object) => {
|
|
const _keys = castArray(keys);
|
|
const copy = Object.assign({}, object);
|
|
_keys.forEach((key) => {
|
|
delete copy[key];
|
|
});
|
|
return copy;
|
|
};
|
|
|
|
/**
|
|
* Picks the specified keys from an object and returns a new object with only those keys.
|
|
*
|
|
* @param keys - The keys to pick from the object
|
|
* @param object - The object to pick the keys from
|
|
* @returns A new object with only the picked keys
|
|
*/
|
|
const pick = (keys, obj) => {
|
|
const result = {};
|
|
for (let i = 0; i < keys.length; i += 1) {
|
|
const key = keys[i];
|
|
if (key in obj)
|
|
result[key] = obj[key];
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Repeats an element a specified number of times.
|
|
*
|
|
* @template T
|
|
* @param element - Element to be repeated
|
|
* @param length - Number of times to repeat element
|
|
* @returns Repeated elements
|
|
*/
|
|
const repeat = (element, length = 0) => {
|
|
const result = new Array(length);
|
|
for (let i = 0; i < length; i += 1) {
|
|
result[i] = element;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Reverses the list
|
|
*
|
|
* @template T
|
|
* @param list - List to be reversed
|
|
* @returns Reversed list
|
|
*/
|
|
const reverse = (list) => Array.prototype.slice.call(list, 0).reverse();
|
|
|
|
/**
|
|
* Capitalize first letter of string
|
|
*
|
|
* @param value - String
|
|
* @returns Capitalized string
|
|
*/
|
|
const upperFirst = (value) => {
|
|
if (!value)
|
|
return value;
|
|
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
};
|
|
|
|
/**
|
|
* Returns a new array with all the values from the original array that are not present in the keys array.
|
|
*
|
|
* @param keys - The keys to pick from the object
|
|
* @param array - Array to filter the values from
|
|
* @returns A new array with without the omitted values
|
|
*/
|
|
const without = (keys, array) => {
|
|
const result = [];
|
|
for (let i = 0; i < array.length; i += 1) {
|
|
const value = array[i];
|
|
if (!keys.includes(value))
|
|
result.push(value);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Parse a string or number to a float
|
|
*
|
|
* @param value - String or number
|
|
* @returns Parsed float
|
|
*/
|
|
const parseFloat$1 = (value) => {
|
|
return typeof value === 'string' ? Number.parseFloat(value) : value;
|
|
};
|
|
|
|
export { adjust, asyncCompose, capitalize, castArray, compose, dropLast, evolve, get, isNil, last, mapValues, matchPercent, omit, parseFloat$1 as parseFloat, pick, repeat, reverse, upperFirst, without };
|