입력받은 숫자를 원화 표기로 변경하기

YiJaeE·2021년 1월 5일
0
post-thumbnail

9876543210을 입력받으면 98억 7,654만 3,210원을 리턴하는 함수를 만들어 보자

구현조건

  1. 0 이상 1조(1000000000000) 미만의 정수
  2. 천 단위에 콤마를 찍는다
  3. 만, 억 단위에 해당 단위를 삽입한다
  4. 금액 사이는 한 칸을 띄운다
  5. 주어진 숫자가 1000000이라면 100만으로 표기
  6. 주어진 숫자가 1000001이라면 100만 1원으로 표기
  7. 원은 마지막에 추가

기능별로 함수를 쪼개자

  1. 새로운 정렬 만들기
  2. 삭제되어야 할 0 걸러내기
  3. 천 단위에 콤마 찍기
  4. 돈 단위 추가하고 배열 재정렬하기
  5. 돈 단위 뒤에 조건에 따라 빈 칸 삽입

1. 새로운 배열 만들기

왜 새로운 배열을 만드나?

기본적으로 원화는 만 단위로 쪼개어진다. 원화 단위(만, 억)가 삽입되는 기준점이 바로 4자리수이기 때문에 4자리씩 쪼개어 이중배열을 만든다.

왜 배열을 뒤집나?

돈은 뒷자리수부터 세기 때문이다. 앞자리수를 기준으로 삼는다면 전체 돈의 사이즈를 가늠하기가 어렵기 때문에 배열을 뒤집는다.

구현 방법

문자열로 변환한 numberToStrnumberToStr의 length에서 4를 뺀 숫자가 0이 될 때까지 4만큼의 간격으로 반복문을 돌려 한 바퀴 돌 때마다 i 만큼 잘린 숫자를 빈 배열에 삽입
예) 987654321의 경우 [3, 2, 1, 0], [7, 6, 5, 4] 순으로 들어가고 [9, 8]은 spliceArray 남아있음
이후 네자리를 충족하지 못한 나머지 배열(spliceArray)을 추가

const numToNuArray = num => {
  const numberToStr = num + '';
  let nuArray = [];
  const spliceArray = [...numberToStr];
  for (let i = numberToStr.length - 4; i > 0; i -= 4) {
    nuArray.push(spliceArray.splice(i));
  }

  nuArray.push(spliceArray);

  return nuArray;
};

2. 삭제되어야 할 0 걸러내기

삭제되어야 할 0이란?

주어진 숫자가 1000000일 때 100만으로 표기하기 위한 나머지 0 네 자리 또는 주어진 숫자가 1000001일 때 100만 1원으로 표기하듯 1 앞에 있는 0 세 자리를 뜻한다.

구현 방법

배열 전체가 0일 때 그 배열을 아예 날릴 수도 있지만 그렇게 되면 중간에 0이 들어갔을 때를 구현할 수 없다. 따라서 다음 두 가지 경우에 해당된다.

  1. 0번 인덱스의 값이 0인 경우와
  2. 현재 인덱스 - 1의 인덱스 값이 빈 문자열이고 현재 인덱스의 값이 0인 경우

이 두 가지 조건에 따라 빈 문자열을 삽입한다.
이 조건에 따르면 배열 전체가 0인 경우와 앞자리가 비어있고 현재 인덱스의 값이 0인 경우 두 가지를 모두 정리할 수 있다.

여기에서 제외되는 케이스는 두 가지다.
1. 현재 인덱스 값이 0이라고 하더라도 바로 앞자리가 빈 문자열이 아닌 경우(다른 숫자인 경우)
2. 현재 인덱스 - 1의 인덱스가 빈 문자열이라고 해도 현재 인덱스 값이 0이 아닌 경우

const isZeroControl = koreanArray => {
  koreanArray.map(zeroControl =>
    zeroControl.map(
      (zero, idx) =>
        (zeroControl[idx] = (idx === 0 || zeroControl[idx - 1] === '') && zero === '0' ? '' : zero),
    ),
  );
};

3. 천 단위에 콤마 찍기

천 단위에 콤마를 찍을 때 이미 삭제되어야 할 0이 삭제된 후이므로 무조건 콤마를 찍으면 안 된다. 0이 삭제되어 123이라는 숫자만 남아있는 배열이 있을 경우 ,123 이라는 형태로 리턴될 것이기 때문이다. 때문에 콤마를 찍을 때 다음과 같은 조건에 따라야 한다.

구현 방법

  1. 배열의 길이가 4여야 한다.
  2. 현재 인덱스 - 1의 인덱스 값이 빈 문자열이 아니어야 한다.
  3. 현재 인덱스가 1이며 현재 인덱스 앞에 쉼표를 삽입한다.
const isInsetComma = koreanArray => {
  koreanArray.map(insertComma =>
    insertComma.map((num, idx) =>
      insertComma.length === 4 && insertComma[idx - 1] !== '' && idx === 1
        ? insertComma.splice(idx, 0, ',')
        : num,
    ),
  );
};

4. 돈 단위 추가하고 배열 재정렬하기

구현 방법

  1. 원은 마지막에 추가하기로 했으니 0번 인덱스는 빈 문자열로 남겨두고 만, 억에 해당하는 문자열을 삽입한 변수의 값을 배열 내부에 삽입한다.
  2. 배열을 재정렬하는 함수를 만든다. 배열 순서를 다시 뒤집어서 정렬하고 이중 배열을 없앤다. 특히 빈 문자열의 경우 마지막에 빈 칸을 삽입하는 작업을 해야하므로 미리 제거해준다.
const monetaryUnit = ['', '만', '억'];

const isInsertUnit = (koreanArray, monetaryUnit) =>
  koreanArray.map((unitArray, idx) => unitArray.push(monetaryUnit[idx]));

const reArrange = koreanArray => {
  return koreanArray
    .reverse()
    .flat()
    .filter(blank => blank !== '');
};

5. 돈 단위 뒤에 조건에 따라 빈 칸 삽입

여기까지 구현하면 리턴되는 모습은 ['1','억','2',',','3','4','5','천' ...] 형태로 되어있다. 마지막으로 배열을 풀기 전에 억, 만, 단위에 따라 빈 칸을 삽입해줘야 한다.

구현 방법

  1. 억, 만 단위 뒤에 빈 칸을 삽입한다.
  2. 100만으로 딱 떨어지는 값일 경우 화폐 단위 뒤에 빈 칸 삽입을 하지 않는다. 100만처럼 딱 떨어지는 값일 경우 배열에는 만 뒤에 값이 존재하지 않는다. 이미 필터로 빈 문자열을 모두 제거했기 때문이다. 따라서 화폐 단위의 다음 인덱스가 undefined가 아닐 때만 빈 칸을 삽입한다.
const isInsertBlank = (monetaryUnit, koreanArray) => {
  monetaryUnit.map(unit =>
    koreanArray.map(
      (korean, idx) =>
        (koreanArray[idx] =
          unit === korean && koreanArray[idx + 1] !== undefined ? `${korean} ` : `${korean}`),
    ),
  );
};

이렇게 만든 함수를 모두 호출하는 함수 하나를 만들면 다음과 같은 모습이 된다.

profile
개발을 개발개발 🐾

0개의 댓글