UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions and classes for everyday development needs.

158 lines (157 loc) 5.35 kB
import { isNumber } from '../guards/primitives.js'; import { _find2NumbersHCF, _find2NumbersLCM } from './helpers.js'; /** * * Utility to generate a random number between a given range. * * If no options are provided, it will generate a random number between `0` and `100` (inclusive). * * If `min` is greater than `max`, it will swap the values and generate a random number. * * @param options - Options for configuring random number generator. * @returns Random number. */ export const getRandomNumber = (options) => { const { min = 0, max = 100, includeMin = true, includeMax = true, } = options || {}; let minimum = min, maximum = max; if (min > max) { [minimum, maximum] = [max, min]; return getRandomNumber({ min: minimum, max: maximum, includeMin, includeMax, }); } if (min === max) { return min; } if (includeMin && includeMax) { // Generate random number between min and max, inclusive return Math.floor(Math.random() * (max - min + 1)) + min; } if (!includeMin && !includeMax) { // Generate random number between min and max, exclusive return Math.floor(Math.random() * (max - min - 1)) + min + 1; } if (includeMin && !includeMax) { // Generate random number between min and max, inclusive of min but exclusive of max return Math.floor(Math.random() * (max - min)) + min; } if (!includeMin && includeMax) { // Generate random number between min and max, exclusive of min but inclusive of max return Math.floor(Math.random() * (max - min)) + min + 1; } return 0; }; /** * * Utility to round a number to given decimal places. * * @param input - Number or `stringified` number to round. * @param options - Options for rounding behavior, including decimal places and return type. * @returns Converted number as `number` (default) or `string` (if `isString` is `true`). */ export const convertToDecimal = (input, options) => { const { decimalPlaces = 2, isString = false } = options || {}; const number = typeof input === 'number' ? input : Number(input); return isString ? number.toFixed(decimalPlaces) : Number(number.toFixed(decimalPlaces)); }; /** * * Calculates the HCF/GCD of multiple numbers. * * @param numbers - List of numbers to find the HCF/GCD for. * @returns The HCF/GCD of all the provided numbers. */ export const calculateHCF = (...numbers) => { const converted = numbers?.map(Number); if (converted?.length === 0) return 0; let hcf = converted[0]; for (let i = 1; i < converted?.length; i++) { hcf = _find2NumbersHCF(hcf, converted[i]); } return hcf; }; /** * * Calculates the LCM/LCD of multiple numbers. * * @param numbers - List of numbers to find the LCM/LCD for. * @returns The LCM/LCD of all the provided numbers. */ export const calculateLCM = (...numbers) => { const converted = numbers?.map(Number); if (converted?.length === 0) return 0; let lcm = converted[0]; for (let i = 1; i < converted?.length; i++) { lcm = _find2NumbersLCM(lcm, converted[i]); } return lcm; }; /** * * Sums up all digits of a number. * * @param num The input number. * @returns The sum of its digits. */ export function sumDigits(num) { return Math.abs(Number(num)) .toString() .split('') .reduce((sum, digit) => sum + Number(digit), 0); } /** * * Sums up numbers. * * @param numbers The input numbers. * @returns The sum of the numbers. */ export function sumNumbers(...numbers) { return numbers ?.map((num) => Number(num)) ?.reduce((sum, number) => sum + number, 0); } /** * * Reverses a number (e.g., `123` → `321`). * * @param num The number to reverse. * @returns The reversed number. */ export function reverseNumber(num) { const reversed = parseInt(Math.abs(Number(num)).toString().split('').reverse().join(''), 10); return Number(num) < 0 ? -reversed : reversed; } /** * * Calculates the average of a set of numbers. * * @param numbers - A list of numbers for which to calculate the average. * @returns The average of the provided numbers. Returns `NaN` if no numbers are valid. */ export function getAverage(...numbers) { let sum = 0; let count = 0; for (const n of numbers) { const num = Number(n); if (typeof num === 'number' && !isNaN(num)) { sum += num; count++; } } return count === 0 ? NaN : Math.round((sum / count) * 1000) / 1000; } /** * * Rounds a number to a specified number of decimal places. * * @param number - The number to round. * @param roundTo - The number of decimal places to round to (default is `2`). * - If `roundTo` is negative, the number is rounded to the left of the decimal point (e.g., `-1` rounds to the nearest 10, `-2` to nearest 100 etc.). * @returns The rounded number, either in float or integer (if a whole number). * * @example * roundNumber(1234.56, -2); // 1200 * roundNumber(1234.56, 1); // 1234.6 */ export function roundNumber(number, roundTo = 2) { const factor = Math.pow(10, roundTo); const num = isNumber(number) ? number : Number(number); return Math.round(num * factor) / factor; }