UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 3.26 kB
{"version":3,"file":"median.cjs","names":["purry"],"sources":["../src/median.ts"],"sourcesContent":["import type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport { purry } from \"./purry\";\n\ntype Median<T extends IterableContainer<number>> =\n | (T extends readonly [] ? never : number)\n | (T extends readonly [unknown, ...Array<unknown>] ? never : undefined);\n\n/**\n * Returns the median of the elements of an array.\n *\n * Only `number` arrays are supported, as `bigint` is unable to represent fractional values.\n *\n * IMPORTANT: The result for empty arrays would be `undefined`, regardless of\n * the type of the array. This approach improves type-checking and ensures that\n * cases where `NaN` might occur are handled properly. To avoid adding this to\n * the return type for cases where the array is known to be non-empty you can use\n * `hasAtLeast` or `isEmpty` to guard against this case.\n *\n * @param data - The array of numbers.\n * @signature\n * R.median(data);\n * @example\n * R.pipe([6, 10, 11], R.median()); // => 10\n * R.median([]); // => undefined\n * @dataFirst\n * @category Number\n */\nexport function median<T extends IterableContainer<number>>(data: T): Median<T>;\n\n/**\n * Returns the median of the elements of an array.\n *\n * Only `number` arrays are supported, as `bigint` is unable to represent fractional values.\n *\n * IMPORTANT: The result for empty arrays would be `undefined`, regardless of\n * the type of the array. This approach improves type-checking and ensures that\n * cases where `NaN` might occur are handled properly. To avoid adding this to\n * the return type for cases where the array is known to be non-empty you can use\n * `hasAtLeast` or `isEmpty` to guard against this case.\n *\n * @signature\n * R.median()(data);\n * @example\n * R.pipe([6, 10, 11], R.median()); // => 10\n * R.pipe([], R.median()); // => undefined\n * @dataLast\n * @category Number\n */\nexport function median(): <T extends IterableContainer<number>>(\n data: T,\n) => Median<T>;\n\nexport function median(...args: ReadonlyArray<unknown>): unknown {\n return purry(medianImplementation, args);\n}\n\nconst numberComparator = (a: number, b: number): number => a - b;\n\nfunction medianImplementation<T extends IterableContainer<number>>(\n data: T,\n): T[number] | undefined {\n if (data.length === 0) {\n return undefined;\n }\n\n // TODO [>2]: When node 18 reaches end-of-life bump target lib to ES2023+ and use `Array.prototype.toSorted` here.\n const sortedData = [...data].sort(numberComparator);\n\n // For odd length, return the middle element\n if (sortedData.length % 2 !== 0) {\n return sortedData[(sortedData.length - 1) / 2];\n }\n\n // For even length, return the mean of the two middle elements\n const middleIndex = sortedData.length / 2;\n\n return (sortedData[middleIndex]! + sortedData[middleIndex - 1]!) / 2;\n}\n"],"mappings":"wCAoDA,SAAgB,EAAO,GAAG,EAAuC,CAC/D,OAAOA,EAAAA,EAAM,EAAsB,EAAK,CAG1C,MAAM,GAAoB,EAAW,IAAsB,EAAI,EAE/D,SAAS,EACP,EACuB,CACvB,GAAI,EAAK,SAAW,EAClB,OAIF,IAAM,EAAa,CAAC,GAAG,EAAK,CAAC,KAAK,EAAiB,CAGnD,GAAI,EAAW,OAAS,GAAM,EAC5B,OAAO,GAAY,EAAW,OAAS,GAAK,GAI9C,IAAM,EAAc,EAAW,OAAS,EAExC,OAAQ,EAAW,GAAgB,EAAW,EAAc,IAAO"}