Files
tools/vue/toolkit/src/composables/math/useAverage/index.ts
T
robonen ab6d8f6ce0
Publish to NPM / Check version changes and publish (push) Failing after 10m34s
build: bump new versions
2026-06-18 02:57:03 +07:00

56 lines
1.9 KiB
TypeScript

import { isArray, sum } from '@robonen/stdlib';
import { computed, toValue } from 'vue';
import type { ComputedRef, MaybeRefOrGetter } from 'vue';
import type { MaybeComputedRefArgs } from '@/types';
/**
* @name useAverage
* @category Math
* @description Reactively compute the average (arithmetic mean) of the provided
* numbers. Accepts either a variadic list of numbers (each a ref, getter, or raw
* value) or a single reactive array whose items may themselves be refs/getters.
* Returns `NaN` when there are no values, mirroring `0 / 0`.
*
* @param {...MaybeRefOrGetter<number>} args The values to average, or a single reactive array of values
* @returns {ComputedRef<number>} A computed ref of the mean (`NaN` when empty)
*
* @example
* const a = ref(1);
* const b = ref(3);
* const avg = useAverage(a, b, 2); // 2
*
* @example
* const list = ref([1, 5, 3]);
* const avg = useAverage(list); // 3
*
* @example
* const list = ref([ref(2), () => 4, 6]);
* const avg = useAverage(list); // 4
*
* @since 0.0.14
*/
export function useAverage(array: MaybeRefOrGetter<Array<MaybeRefOrGetter<number>>>): ComputedRef<number>;
export function useAverage(...args: Array<MaybeRefOrGetter<number>>): ComputedRef<number>;
export function useAverage(...args: MaybeComputedRefArgs<number>): ComputedRef<number> {
return computed<number>(() => {
// Collect into a single flat numeric array so we can reuse stdlib `sum`
// and divide by the real count in one pass — no intermediate flatMap.
const values: number[] = [];
for (const arg of args) {
const value = toValue(arg);
if (isArray(value)) {
for (const inner of value)
values.push(toValue(inner));
}
else {
values.push(value);
}
}
// Empty -> NaN (0 / 0), matching the mathematical definition of a mean.
return sum(values) / values.length;
});
}