toCamelCase

Codewars 문제 풀이

toCamelCase 문제

대시/밑줄로 구분된 단어를 카멜케이스로 변환하는 메서드/함수를 완성하세요.
출력 내의 첫 번째 단어는 원래 단어가 대문자인 경우에만 대문자로 표시해야 합니다
(Upper Camel Case라고도 하며 종종 Pascal 케이스라고도 함).

예시

console.log(toCamelCase("the-stealth-warrior")); //"theStealthWarrior"
console.log(toCamelCase("The_Stealth_Warrior")); //"theStealthWarrior"

나의 풀이

function toCamelCase(str) {
  if (str.includes("-")) {
    return str.replace(/-./g, (match) => {
      return match[1].toUpperCase();
    });
  } else if (str.includes("_")) {
    return str.replace(/_./g, (match) => {
      return match[1].toUpperCase();
    });
  } else {
    return str;
  }
}
  1. 대시-와 언더바_를 동시에 검색하면 좋겠지만 생각나지 않아 if...else문으로 조건을 나누었다.
  2. toCamelCase함수의 인수로 문자열을 받기 때문에 String.prototype.replace()메서드에 정규표현식과 치환함수를 이용해 변환하는 방법을 생각했다.
    정규표현식 /-./g-와 임의의 한 문자로 이뤄진 문자열을 매치한다. 치환함수의 인수로 매치결과가 전달되는데 이 문제의 예시로는 -s-w가 전달된다. (플래그로 g를 설정했기 때문에 모든 문자열을 전역검색해 결과를 전달할 수 있다.)
  3. 치환함수에 매치결과를 받으면 대시를 삭제하고 바로 뒤 문자열 즉, match[1]을 대문자로 변경하는 작업이 필요하다. 때문에 .toUpperCase()메서드를 사용했다.
  4. 언더바의 경우도 else if를 이용해 대시와 똑같은 방법을 사용했다.
  5. 언더바와 대시가 없는 문자열인 경우 카멜케이스로 변경할 필요가 없기 때문에 그대로 다시 반환시킨다.

다른 사람 풀이

rseidelsohn

function toCamelCase(str) {
  return str.replace(/[-_]+\w/gi, function (match) {
    return match.charAt(match.length - 1).toUpperCase();
  });
}
  1. []내의 문자는 or로 동작한다. [-_]- or _를 의미한다. if...else문으로 나누는 번거로운 과정이 필요 없다!
  2. +는 앞선 패턴을 한 번 이상 반복한다. --, ___ 모두 검색할 수 있다.
  3. \w는 알파벳, 숫자, 언더스코어를 의미한다.(= [A-Za-z0-9_)]) 대시나 언더스코어 다음에 올 문자를 받을 수 있다.
  4. 플래그 /gi 대소문자 상관없이 전역검색한다.
  5. String.prototype.charAt() 메서드는 인수로 전달받은 인덱스에 위치한 문자를 검색해 반환한다. 여기서 match.length -1로 설정한 이유는 아래와 같다.
//match[1]의 경우
toCamelCase("---to-my-oooooold-----friend"); //-oMyOooooold-riend

//match.charAt(match.length - 1)의 경우
toCamelCase("---to-my-oooooold-----friend"); //ToMyOoooooldFriend

나의 방법이었던 match[1]의 값은 ---to, -m, -o, -----f는 각각 -, m, o, -이 된다. 그래서 만약 대시나 언더바가 2개 이상이면 원하는 결과가 나올 수 없다. 결국 대문자로 변경할 문자열은 마지막에 있기 때문에 match.charAt(match.length - 1)로 설정하면 언더바와 대시가 몇 개가 있든 상관없이 잘 작동할 수 있다.

[-_]+\w/gi[-_]+./gi 차이는 무엇일까
\w는 알파벳, 숫자, 언더스코어를 의미하고, .은 임의의 문자 한 개를 의미한다. 즉, .은 공백도 포함할 수 있다. 만약 전달된 인수에 공백이 있다면 아래와 같이 차이가 난다.

//[-_]+\w/gi 경우
console.log(toCamelCase("--    -to-my-oooooold-----friend"));//--    ToMyOoooooldFriend
//[-_]+./gi 경우
console.log(toCamelCase("--    -to-my-oooooold-----friend"));//     ToMyOoooooldFriend

kirilloid

function toCamelCase(str){
  return str.replace(/[-_](.)/g, (_, c) => c.toUpperCase());
}
  1. 임의의 문자 .을 괄호()에 넣어 별도의 catcher 그룹을 만들었다.
  2. 치환함수에 첫 번째 매개변수는 상관하지 않겠다는 의미로 _ 언더바를 두었다.
  3. 두 번째 매개변수는 catcher의 약자 c를 의미하는 것 같다. 이 매개변수는 1번에서 설명한 별도로 빼둔 그룹인데 언더바 혹은 대시바 바로뒤 문자 하나가 값으로 설정된다.
  4. 최종으로 c.toUpperCase()로 대문자로 변경후 출력한다.

하지만 이 코드는 toCamelCase("---to-my-oooooold-----friend");의 경우 -ToMyOooooold--Friend를 반환하므로 아래와 같이 정규표현식에 + 붙이면 좋을 것 같다.

function toCamelCase(str){
  return str.replace(/[-_]+(.)/g, (_, c) => c.toUpperCase());
}

toCamelCase("---to-my-oooooold-----friend"); //ToMyOoooooldFriend

좋은 웹페이지 즐겨찾기