UNPKG

@modern-kit/utils

Version:
1 lines 5.6 kB
{"version":3,"file":"index.mjs","sources":["../../../src/formatter/formatNumberWithUnits/index.ts"],"sourcesContent":["import { formatNumberWithCommas } from '../formatNumberWithCommas';\nimport { isNumber } from '../../validator/isNumber';\n\ninterface Unit {\n unit: string;\n value: number;\n}\n\ninterface FormatNumberWithUnitsOptions {\n units: Unit[] | readonly Unit[];\n commas?: boolean;\n decimal?: number;\n}\n\n/**\n * @description 쉼표 사용 여부에 따라 숫자를 포맷팅하는 함수\n */\nconst formatNumberWithConditionalCommas = (\n value: number | string,\n commas: boolean\n) => {\n return commas ? formatNumberWithCommas(value) : value;\n};\n\n/**\n * @description 주어진 단위 배열에 따라 숫자를 포맷팅하는 함수\n */\nconst getFormattedNumberWithUnits = (\n value: number,\n options: FormatNumberWithUnitsOptions\n) => {\n const { units, commas = true, decimal = 0 } = options;\n const sortedUnits = [...units].sort((a, b) => b.value - a.value);\n\n const absoluteValue = Math.abs(value);\n const negativeSign = value < 0 ? '-' : '';\n\n let formattedResult = '';\n let remainingValue = absoluteValue;\n\n // unit 별로 나누기\n for (let i = 0; i < sortedUnits.length; i++) {\n const { unit, value: unitValue } = units[i];\n const quotient = Math.floor(remainingValue / unitValue);\n const space = ' ';\n\n if (quotient <= 0) continue;\n\n formattedResult += `${formatNumberWithConditionalCommas(\n quotient,\n commas\n )}${unit}${space}`;\n remainingValue %= unitValue;\n }\n\n // 남은 값이 있으면 추가\n if (remainingValue > 0) {\n formattedResult += `${formatNumberWithConditionalCommas(\n remainingValue.toFixed(decimal),\n commas\n )}`;\n }\n\n return `${negativeSign}${formattedResult.trim()}`;\n};\n\n/**\n * @description `숫자` 혹은 `숫자로 이루어진 문자열`을 주어진 `단위` 별로 포맷팅하는 함수입니다.\n *\n * - 천 단위마다 쉼표 사용 여부(`commas`)를 선택할 수 있습니다. 기본값은 `true`입니다.\n * - 허용 할 소수점 자리수(`decimal`)를 선택할 수 있습니다. 기본값은 `0`입니다.\n *\n * @param {number | string} value - 포맷팅할 숫자 또는 숫자로 이루어진 문자열\n * @param {FormatNumberWithUnitsOptions} options - 포맷팅 옵션\n * @param {Unit[] | readonly Unit[]} options.units - 사용할 단위 배열\n * @param {boolean} [options.commas=true] - 쉼표 사용 여부\n * @param {number} [options.decimal=0] - 소수점 자리수\n * @returns {string} 단위 별로 나눠져 포맷팅된 문자열\n *\n * @throws 주어진 숫자가 숫자 혹은 숫자로 이뤄진 문자열이 아닐 경우 에러 발생\n *\n * @example\n * const KRW_UNITS = [\n * { unit: '억', value: 100_000_000 },\n * { unit: '만', value: 10_000 },\n * ] as const;\n *\n * formatNumberWithUnits(123456789, { units: KRW_UNITS });\n * formatNumberWithUnits('123456789', { units: KRW_UNITS });\n * // \"1억 2,345만 6,789\"\n *\n * formatNumberWithUnits(-123456789, { units: KRW_UNITS });\n * formatNumberWithUnits('-123456789', { units: KRW_UNITS });\n * // \"-1억 2,345만 6,789\"\n *\n * @example\n * // 콤마 사용 여부\n * formatNumberWithUnits(123456789, { units: KRW_UNITS, commas: false });\n * // \"1억 2345만 6789\"\n * formatNumberWithUnits(123456789, { units: KRW_UNITS, commas: true });\n * // \"1억 2,345만 6,789\"\n *\n * @example\n * // 소수점 허용 여부\n * formatNumberWithUnits(123456789.12, { units: KRW_UNITS, decimal: 0 });\n * // \"1억 2,345만 6,789\"\n * formatNumberWithUnits(123456789.12, { units: KRW_UNITS, decimal: 2 });\n * // \"1억 2,345만 6,789.12\"\n */\nexport function formatNumberWithUnits(\n value: number | string,\n options: FormatNumberWithUnitsOptions\n): string {\n const valueToUse = isNumber(value) ? value : Number(value);\n\n if (isNaN(valueToUse)) {\n throw new Error('value는 숫자 혹은 숫자로 이뤄진 문자열이여야 합니다.');\n }\n\n return getFormattedNumberWithUnits(valueToUse, options);\n}\n"],"names":[],"mappings":";;;AAiBA,MAAM,iCAAA,GAAoC,CACxC,KAAA,EACA,MAAA,KACG;AACH,EAAA,OAAO,MAAA,GAAS,sBAAA,CAAuB,KAAK,CAAA,GAAI,KAAA;AAClD,CAAA;AAKA,MAAM,2BAAA,GAA8B,CAClC,KAAA,EACA,OAAA,KACG;AACH,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,GAAS,IAAA,EAAM,OAAA,GAAU,GAAE,GAAI,OAAA;AAC9C,EAAA,MAAM,WAAA,GAAc,CAAC,GAAG,KAAK,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAA;AAE/D,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AACpC,EAAA,MAAM,YAAA,GAAe,KAAA,GAAQ,CAAA,GAAI,GAAA,GAAM,EAAA;AAEvC,EAAA,IAAI,eAAA,GAAkB,EAAA;AACtB,EAAA,IAAI,cAAA,GAAiB,aAAA;AAGrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,CAAY,QAAQ,CAAA,EAAA,EAAK;AAC3C,IAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,SAAA,EAAU,GAAI,MAAM,CAAC,CAAA;AAC1C,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,cAAA,GAAiB,SAAS,CAAA;AACtD,IAAA,MAAM,KAAA,GAAQ,GAAA;AAEd,IAAA,IAAI,YAAY,CAAA,EAAG;AAEnB,IAAA,eAAA,IAAmB,CAAA,EAAG,iCAAA;AAAA,MACpB,QAAA;AAAA,MACA;AAAA,KACD,CAAA,EAAG,IAAI,CAAA,EAAG,KAAK,CAAA,CAAA;AAChB,IAAA,cAAA,IAAkB,SAAA;AAAA,EACpB;AAGA,EAAA,IAAI,iBAAiB,CAAA,EAAG;AACtB,IAAA,eAAA,IAAmB,CAAA,EAAG,iCAAA;AAAA,MACpB,cAAA,CAAe,QAAQ,OAAO,CAAA;AAAA,MAC9B;AAAA,KACD,CAAA,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,CAAA,EAAG,YAAY,CAAA,EAAG,eAAA,CAAgB,MAAM,CAAA,CAAA;AACjD,CAAA;AA6CO,SAAS,qBAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,MAAM,aAAa,QAAA,CAAS,KAAK,CAAA,GAAI,KAAA,GAAQ,OAAO,KAAK,CAAA;AAEzD,EAAA,IAAI,KAAA,CAAM,UAAU,CAAA,EAAG;AACrB,IAAA,MAAM,IAAI,MAAM,sIAAkC,CAAA;AAAA,EACpD;AAEA,EAAA,OAAO,2BAAA,CAA4B,YAAY,OAAO,CAAA;AACxD;;;;"}