remeda
Version:
A utility library for JavaScript and Typescript.
1 lines • 3.82 kB
Source Map (JSON)
{"version":3,"file":"sumBy.cjs","names":["purry"],"sources":["../src/sumBy.ts"],"sourcesContent":["import { purry } from \"./purry\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\n\ntype SumBy<\n T extends IterableContainer,\n U extends bigint | number,\n> = T extends readonly []\n ? 0\n : T extends readonly [unknown, ...(readonly unknown[])]\n ? U\n : U | 0;\n\n/**\n * Returns the sum of the elements of an array using the provided mapper.\n *\n * Works for both `number` and `bigint` mappers, but not mappers that return both\n * types.\n *\n * IMPORTANT: The result for empty arrays would be 0 (`number`) regardless of\n * the type of the mapper; to avoid adding this to the return type for cases\n * where the array is known to be non-empty you can use `hasAtLeast` or\n * `isEmpty` to guard against this case.\n *\n * @param callbackfn - Predicate function.\n * @signature\n * R.sumBy(fn)(array)\n * @example\n * R.pipe(\n * [{a: 5}, {a: 1}, {a: 3}],\n * R.sumBy(x => x.a)\n * ) // 9\n *\n * R.pipe(\n * [{a: 5n}, {a: 1n}, {a: 3n}],\n * R.sumBy(x => x.a)\n * ) // 9n\n * @dataLast\n * @category Array\n */\nexport function sumBy<T extends IterableContainer>(\n callbackfn: (value: T[number], index: number, data: T) => number,\n): (items: T) => SumBy<T, number>;\nexport function sumBy<T extends IterableContainer>(\n callbackfn: (value: T[number], index: number, data: T) => bigint,\n): (items: T) => SumBy<T, bigint>;\n\n/**\n * Returns the sum of the elements of an array using the provided mapper.\n *\n * Works for both `number` and `bigint` mappers, but not mappers that can return both\n * types.\n *\n * IMPORTANT: The result for empty arrays would be 0 (`number`) regardless of\n * the type of the mapper; to avoid adding this to the return type for cases\n * where the array is known to be non-empty you can use `hasAtLeast` or\n * `isEmpty` to guard against this case.\n *\n * @param data - The array.\n * @param callbackfn - Predicate function.\n * @signature\n * R.sumBy(array, fn)\n * @example\n * R.sumBy(\n * [{a: 5}, {a: 1}, {a: 3}],\n * x => x.a\n * ) // 9\n * R.sumBy(\n * [{a: 5n}, {a: 1n}, {a: 3n}],\n * x => x.a\n * ) // 9n\n * @dataFirst\n * @category Array\n */\nexport function sumBy<T extends IterableContainer>(\n data: T,\n callbackfn: (value: T[number], index: number, data: T) => number,\n): SumBy<T, number>;\nexport function sumBy<T extends IterableContainer>(\n data: T,\n callbackfn: (value: T[number], index: number, data: T) => bigint,\n): SumBy<T, bigint>;\n\nexport function sumBy(...args: readonly unknown[]): unknown {\n return purry(sumByImplementation, args);\n}\n\nconst sumByImplementation = <T>(\n array: readonly T[],\n callbackfn: (value: T, index: number, data: readonly T[]) => bigint | number,\n): bigint | number => {\n const iter = array.entries();\n\n const firstEntry = iter.next();\n if (\"done\" in firstEntry && firstEntry.done) {\n return 0;\n }\n\n const {\n value: [, firstValue],\n } = firstEntry;\n let sum = callbackfn(firstValue, 0, array);\n for (const [index, item] of iter) {\n const summand = callbackfn(item, index, array);\n\n // @ts-expect-error [ts2365] -- Typescript can't infer that all elements will be a number of the same type.\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n sum += summand;\n }\n return sum;\n};\n"],"mappings":"wCAkFA,SAAgB,EAAM,GAAG,EAAmC,CAC1D,OAAOA,EAAAA,EAAM,EAAqB,EAAK,CAGzC,MAAM,GACJ,EACA,IACoB,CACpB,IAAM,EAAO,EAAM,SAAS,CAEtB,EAAa,EAAK,MAAM,CAC9B,GAAI,SAAU,GAAc,EAAW,KACrC,MAAO,GAGT,GAAM,CACJ,MAAO,EAAG,IACR,EACA,EAAM,EAAW,EAAY,EAAG,EAAM,CAC1C,IAAK,GAAM,CAAC,EAAO,KAAS,EAAM,CAChC,IAAM,EAAU,EAAW,EAAM,EAAO,EAAM,CAI9C,GAAO,EAET,OAAO"}