티스토리 뷰

Spinal Tap Case

  • 문제

    문자열을 spinal case로 변환하라. Spinal case란 소문자로 이루어지고 dash(-)로 연결된 문자열을 말한다.

    • 예시

      spinalCase("This Is Spinal Tap") should return "this-is-spinal-tap".
      Passed
      spinalCase("thisIsSpinalTap") should return "this-is-spinal-tap".
      Passed
      spinalCase("The_Andy_Griffith_Show") should return "the-andy-griffith-show".
      Passed
      spinalCase("Teletubbies say Eh-oh") should return "teletubbies-say-eh-oh".
      Passed
      spinalCase("AllThe-small Things") should return "all-the-small-things".
      

       

  • 내가 푼 답

    function spinalCase(str) {
        var newStr = str.split(/\W|_/).join("-");
        
        function replacer(match, p1, p2) {
            return [p1, p2].join('-');
        }
    
        if(newStr.match(/(?<=[a-z])[A-Z](?=[a-z])/)) {
            newStr = newStr.replace(/([a-z]+)([A-Z]+)(?=[a-z]+)/g, replacer).split(/\W/).join('-');
        } 
        return newStr.toLowerCase();
    }
    

    replace 메소드를 쓸 때에 매개변수로 함수를 쓸 수 있다는 것을 구글링하다가 처음 알았다. mdn문서의 replace를 참조하여 replacer 함수를 만들었다.

    그리고 정규식에 lookahead(?=)는 알고 있었는데, 매치하고자 하는 문자열 전에 특정 문자가 있는지 찾을 수 없을까 구글링하다가 lookbehind 기능(?<=)이 ES2018에 새로 추가되었다는 것을 알았다.

     

  • Basic Solution

    function spinalCase(str) {
      // Create a variable for the white space and underscores.
      var regex = /\s+|_+/g;
    
      // Replace low-upper case to low-space-uppercase
      str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
    
      // Replace space and underscore with -
      return str.replace(regex, '-').toLowerCase();
    }
    

    나도 소문자 뒤에 있는 대문자를 발견하고 그 앞을 구분해야 한다는 것을 알았다. 이 솔루션은 replace를 쓸 때 매개변수로 함수를 쓰지 않고 '$1 $2' 로 간단하게 그 사이에 띄어쓰기를 넣었다. '$1' 은 첫 번째 캡처링 그룹을 의미하고 '$1''$2' 사이를 띄어써야 소문자와 대문자 사이에 띄어쓰기가 되는 것을 의미한다.

 

  • Intermediate Solution

    function spinalCase(str) {
      // Replace low-upper case to low-space-uppercase
      str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
      // Split on whitespace and underscores and join with dash
      return str.toLowerCase().split(/(?:_| )+/) .join('-');
    }
    

    ?: 는 비포획그룹을 의미한다. (mdn 참조) 예를 들어 /foo{1,2}/에서는 o만 해당되지만 /(?:foo){1,2}/ 는 foo전체에 해당된다.

     

  • Advanced Solution

    function spinalCase(str) {
      return str.split(/\s|_|(?=[A-Z])/).join('-').toLowerCase();
    }
    

    lookahead로 한 번에 쪼갤 수도 있다.

'Data Structure & Algorithm' 카테고리의 다른 글

JS_Sum Primes  (0) 2019.04.03
탐욕 알고리즘  (0) 2019.04.03
다익스트라 알고리즘  (0) 2019.03.30
너비 우선 탐색(BFS)  (0) 2019.03.30
해시 테이블  (0) 2019.03.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함