Skip to content

Commit

Permalink
refactor(utils): formatNumberWithUnits 로직 개선 및 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
ssi02014 committed Jan 12, 2025
1 parent ce4bdb1 commit 1157a1c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 29 deletions.
9 changes: 8 additions & 1 deletion docs/docs/utils/formatter/formatNumberWithCommas.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# formatNumberWithCommas

`숫자로 이루어진 문자열` 또는 `숫자`를 입력하면 천 단위로 `(,)comma`를 추가한 문자열을 반환하는 함수입니다.
주어진 `숫자` 또는 `문자열`에 포함된 숫자를 천 단위로 `(,)comma`를 추가한 문자열을 반환하는 함수입니다.

<br />

Expand All @@ -16,13 +16,20 @@ function formatNumberWithCommas(value: number | string): string
```ts title="typescript"
import { formatNumberWithCommas } from '@modern-kit/utils';
// 숫자
formatNumberWithCommas(200); // '200'
formatNumberWithCommas(3000); // '3,000'
formatNumberWithCommas(-123123123); // '-123,123,123'
formatNumberWithCommas(123456.12345); // '123,456.12345'
// 숫자로 이뤄진 문자열
formatNumberWithCommas('200'); // '200'
formatNumberWithCommas('3000'); // '3,000'
formatNumberWithCommas('-123123123'); // '-123,123,123'
formatNumberWithCommas('123456.12345'); // '123,456.12345'
// 일반적인 문자열
formatNumberWithCommas('1433만 4567'); // '1,433만 4,567'
formatNumberWithCommas('1433만 4567.12345'); // '1,433만 4,567.12345'
formatNumberWithCommas('1234ddd'); // '1,234ddd'
```
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,24 @@ describe('formatNumberWithUnits', () => {
});

it('decimal가 주어진 값에 따라 소수점 자리수를 적용해야 합니다.', () => {
// units 옵션이 주어지지 않음
expect(formatNumberWithUnits(1234567.123, { decimal: 2 })).toBe(
'1,234,567.12'
);

// units 옵션이 주어짐
expect(
formatNumberWithUnits(1234567.123, { decimal: 2, units: KRW_UNITS })
).toBe('123만 4,567.12');

// 만약, floorUnit가 1보다 크면 소수점 자리수를 적용하지 않습니다.
// floorUnit이 주어지면 소수점 자리수를 적용하지 않습니다.
expect(
formatNumberWithUnits(1234567.123, {
decimal: 2,
floorUnit: 1000,
units: KRW_UNITS,
})
).toBe('123만 4,000');

// units 옵션이 주어지지 않으면 기본 단위로 포맷팅
expect(formatNumberWithUnits(1234567.123, { decimal: 2 })).toBe(
'1,234,567.12'
);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,77 @@
import { formatNumberWithCommas } from '../../formatter/formatNumberWithCommas';
import { FormatNumberWithUnitsOptions } from './formatNumberWithUnits.types';

interface FormatOptions {
value: number;
decimal: number;
commas: boolean;
space: boolean;
unit: string;
}

/**
* @description 쉼표 사용 여부에 따라 숫자를 포맷팅하는 함수
*
* @param {number} value - 포맷팅할 숫자
* @param {boolean} commas - 쉼표 사용 여부
* @returns {string} 포맷팅된 문자열
*/
const getNumberWithConditionalCommas = (
const formatNumberWithConditionalCommas = (
value: number | string,
commas: boolean
): string => {
return commas ? formatNumberWithCommas(value) : String(value);
};

/**
* @description 남은 값을 포맷팅하는 내부 유틸 함수
*
* @param {FormatOptions} options - 포맷팅 옵션
* @param {number} options.decimal - 소수점 자리수
* @param {boolean} options.commas - 쉼표 사용 여부
* @returns {string} 포맷팅된 문자열
*/
const formatRemainingValue = ({
value,
decimal,
commas,
}: Omit<FormatOptions, 'space' | 'unit'>): string => {
const formattedValue = Number.isInteger(value)
? value
: value.toFixed(decimal);
return formatNumberWithConditionalCommas(formattedValue, commas);
};

/**
* @description 숫자에 단위를 추가하고 포맷팅하는 내부 유틸 함수
*
* @param {FormatOptions} options - 포맷팅 옵션
* @param {number} options.value - 포맷팅할 숫자
* @param {string} options.unit - 단위
* @param {boolean} options.commas - 쉼표 사용 여부
* @param {boolean} options.space - 단위 사이 공백 추가 여부
* @returns {string} 포맷팅된 문자열
*/
const formatUnitValue = ({
value,
unit,
commas,
space,
}: Omit<FormatOptions, 'decimal'>): string => {
return `${formatNumberWithConditionalCommas(value, commas)}${unit}${
space ? ' ' : ''
}`;
};

/**
* @description 주어진 단위(units)에 따라 숫자를 포맷팅하는 함수
*
* @param {number} value - 포맷팅할 숫자 값
* @param {Required<FormatNumberWithUnitsOptions>} options - 포맷팅 옵션
* @param {boolean} options.commas - 천 단위 구분 쉼표 사용 여부입니다.
* @param {boolean} options.space - 단위 사이 공백 추가 여부입니다.
* @param {number} options.decimal - 소수점 자릿수입니다.
* @param {number} options.floorUnit - 버림 단위입니다.
* @param {number} options.decimal - 소수점 자리수입니다.
* @returns {string} 포맷팅된 문자열
*/
export const getFormattedValueWithUnits = (
Expand Down Expand Up @@ -54,24 +103,22 @@ export const getFormattedValueWithUnits = (

if (quotient <= 0) continue;

formattedResult += `${getNumberWithConditionalCommas(
quotient,
commas
)}${unit}${space ? ' ' : ''}`;

formattedResult += formatUnitValue({
value: quotient,
unit,
commas,
space,
});
remainingValue %= value;
}

// 남은 remainingValue가 있으면 추가
if (remainingValue > 0) {
const formattedValue = Number.isInteger(remainingValue)
? remainingValue
: remainingValue.toFixed(decimal);

formattedResult += `${getNumberWithConditionalCommas(
formattedValue,
commas
)}`;
formattedResult += formatRemainingValue({
value: remainingValue,
decimal,
commas,
});
}

// 음수일 경우 앞에 '-' 붙이며, 앞/뒤 공백 제거
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ describe('formatNumberWithSymbol', () => {
formatValueWithSymbol('-1,234,567', { symbol: '$', position: 'prefix' })
).toBe('-$1,234,567');
});

it('좌우 공백은 제거 후 포맷팅되어야 합니다.', () => {
expect(formatValueWithSymbol(' 1000 ', { symbol: '원' })).toBe(
'1000원'
);
});
});

describe('옵션 적용', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function formatValueWithSymbol(
options: FormatNumberWithSymbolOptions = {}
): string {
const { symbol = '', position = 'suffix', space = false } = options;
const valueToUse = String(value).trim();
const valueToUse = String(value);
const isNegative = valueToUse.startsWith('-');

return getFormattedNumberWithSymbol(valueToUse, {
Expand Down

0 comments on commit 1157a1c

Please sign in to comment.