UNPKG

@byloth/core

Version:

An unopinionated collection of useful functions and classes that I use widely in all my projects. 🔧

134 lines (119 loc) • 3.28 kB
import { ValueException } from "../models/exceptions/index.js"; import { zip } from "./iterator.js"; /** * Computes the average of a given list of values. * The values can be weighted using an additional list of weights. * * --- * * @example * ```ts * average([1, 2, 3, 4, 5]); // 3 * average([6, 8.5, 4], [3, 2, 1]); // 6.5 * ``` * * --- * * @template T The type of the values in the list. It must be or extend a `number` object. * * @param values * The list of values to compute the average. * * It must contain at least one element. Otherwise, a {@link ValueException} will be thrown. * * @param weights * The list of weights to apply to the values. * It should contain the same number of elements as the values list or * the smaller number of elements between the two lists will be considered. * * The sum of the weights must be greater than zero. Otherwise, a {@link ValueException} will be thrown. * * @returns The average of the specified values. */ export function average<T extends number>(values: Iterable<T>, weights?: Iterable<number>): number { if (weights === undefined) { let _sum = 0; let _index = 0; for (const value of values) { _sum += value; _index += 1; } if (_index === 0) { throw new ValueException("You must provide at least one value."); } return _sum / _index; } let _sum = 0; let _count = 0; let _index = 0; for (const [value, weight] of zip(values, weights)) { if (weight <= 0) { throw new ValueException(`The weight for the value #${_index} must be greater than zero.`); } _sum += value * weight; _count += weight; _index += 1; } if (_index === 0) { throw new ValueException("You must provide at least one value and weight."); } if (_count <= 0) { throw new ValueException("The sum of weights must be greater than zero."); } return _sum / _count; } /** * An utility function to compute the hash of a given string. * * The hash is computed using a simple variation of the * {@link http://www.cse.yorku.ca/~oz/hash.html#djb2|djb2} algorithm. * However, the hash is garanteed to be a 32-bit signed integer. * * --- * * @example * ```ts * hash("Hello, world!"); // -1880044555 * hash("How are you?"); // 1761539132 * ``` * * --- * * @param value The string to hash. * * @returns The hash of the specified string. */ export function hash(value: string): number { let hashedValue = 0; for (let index = 0; index < value.length; index += 1) { const char = value.charCodeAt(index); hashedValue = ((hashedValue << 5) - hashedValue) + char; hashedValue |= 0; } return hashedValue; } /** * Sums all the values of a given list. * * --- * * @example * ```ts * sum([1, 2, 3, 4, 5]); // 15 * ``` * * --- * * @template T The type of the values in the list. It must be or extend a `number` object. * * @param values The list of values to sum. * * @returns The sum of the specified values. */ export function sum<T extends number>(values: Iterable<T>): number { let _sum = 0; for (const value of values) { _sum += value; } return _sum; }