요구사항

단순 처리

일단 if문으로 각 경우에 해당하는 로직을 간단하게 만들 수 있습니다.

// example-1
function masking(str: string) {
  if (typeof str !== 'string' || str.length === 0) throw new Error('not string or empty.');

  if (str.length === 1) {
    return str;
  } else if (str.length === 2) {
    return str[0] + '*';
  } else if (str.length < 6) {
    return str[0] + '*'.repeat(str.length-2) + str[str.length-1];
  } else {
    return str[0] + '*'.repeat(4) + str.slice(5);
  }
}

공통 로직 찾기

코드에 비슷한 로직이 많이 보입니다. 요구사항을 잘 읽어보면, 크게 3부분으로 나눌 수 있습니다. 마스킹 하지 않은 앞부분, 마스킹 영역, 마스킹 하지 않은 뒷부분 코드를 그대로 옮겨봅니다.

// example-2
function masking(str: string) {
  if (typeof str !== 'string' || str.length === 0) throw new Error('not string or empty.');

  if (str.length === 1) return str;

  const prefix = str[0];
  const masked = str.length === 2 ? '*' : '*'.repeat(str.length < 6 ? str.length-2 : 4);
  const postfix = str.length === 2 ? '' : str.length < 6 ? str[str.length-1] : str.slice(5);

  return `${prefix}${masked}${postfix}`;
}

3항식을 좀 다듬어봅니다.

// example-2-1
function masking(str: string) {
  if (typeof str !== 'string' || str.length === 0) throw new Error('not string or empty.');

  const len = str.length;

  if (len === 1) return str;

  const prefix = str[0];
  const masked = len === 2 ? '*' : '*'.repeat(len < 6 ? len-2 : 4);
  const postfix = len === 2 ? '' : str.slice(len < 6 ? len-1 : 5);

  return `${prefix}${masked}${postfix}`;
}

postfix와 masked 의 수식이 유사합니다. len-2:4 ⇒ len-1:5 로 +1 되었음을 알 수 있습니다. 즉, postfix는 masked 의 길이 이후로 잘라내면 된다는걸 알 수 있습니다.

// example-2-2
function masking(str: string) {
  if (typeof str !== 'string' || str.length === 0) throw new Error('not string or empty.');

  const len = str.length;

  if (len === 1) return str;

  const prefix = str[0];
  const maskingLen = len === 2 ? 1 : len < 6 ? len-2 : 4;
  const masked = '*'.repeat(maskingLen);
  const postfix = str.slice(maskingLen+1);

  return `${prefix}${masked}${postfix}`;
}

조건문을 다듬어 봅니다. len가 3~5인 경우, len-2 값을 취합니다. 각각 1,2,3이 되고, len이 6이상인 경우 4로 고정됩니다. 즉, len-2 와 4 중 최소값을 취하면 됩니다. 단, len이 2인 경우 len-2는 0 이지만, 1이 되어야 합니다.

// example-2-3
function masking(str: string) {
  if (typeof str !== 'string' || str.length === 0) throw new Error('not string or empty.');

  const len = str.length;

  if (len === 1) return str;

  const prefix = str[0];
  const maskingLen = Math.min(len-2, 4) || 1;
  const masked = '*'.repeat(maskingLen);
  const postfix = str.slice(maskingLen+1);

  return `${prefix}${masked}${postfix}`;
}