import { computed, toValue } from 'vue'; import type { ComputedRef, MaybeRefOrGetter } from 'vue'; export type UseArrayReducer = (accumulator: PV, currentValue: CV, currentIndex: number) => R; export type UseArrayReduceReturn = ComputedRef; /** * @name useArrayReduce * @category Array * @description Reactive `Array.prototype.reduce`, with an optional initial value. * * @param {MaybeRefOrGetter[]>} list The source array (items can be reactive) * @param {UseArrayReducer} reducer A reducer callback applied to each element * @returns {UseArrayReduceReturn} The reduced value * * @example * const list = ref([1, 2, 3, 4]); * const sum = useArrayReduce(list, (acc, n) => acc + n); // 10 * * @since 0.0.15 */ export function useArrayReduce( list: MaybeRefOrGetter>>, reducer: UseArrayReducer, ): UseArrayReduceReturn; /** * @name useArrayReduce * @category Array * @description Reactive `Array.prototype.reduce`, with an optional initial value. * * @param {MaybeRefOrGetter[]>} list The source array (items can be reactive) * @param {UseArrayReducer} reducer A reducer callback applied to each element * @param {MaybeRefOrGetter} initialValue A reactive value to seed the accumulator with * @returns {UseArrayReduceReturn} The reduced value * * @example * const list = ref([1, 2, 3, 4]); * const sum = useArrayReduce(list, (acc, n) => acc + n, 100); // 110 * * @since 0.0.15 */ export function useArrayReduce( list: MaybeRefOrGetter>>, reducer: UseArrayReducer, initialValue: MaybeRefOrGetter, ): UseArrayReduceReturn; export function useArrayReduce( list: MaybeRefOrGetter>>, reducer: UseArrayReducer, initialValue?: MaybeRefOrGetter, ): UseArrayReduceReturn { const step = ( accumulator: U, current: MaybeRefOrGetter, index: number, ): U => reducer(accumulator, toValue(current), index); // Capture presence here (arguments.length, not a default value) so that an // explicitly-passed `undefined` is still honoured as a real initial value. const hasInitial = arguments.length >= 3; return computed(() => { const resolved = toValue(list); return hasInitial ? resolved.reduce(step, toValue(initialValue as MaybeRefOrGetter)) : (resolved as unknown as U[]).reduce(step as unknown as (a: U, c: U, i: number) => U); }); }