ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [알고리즘/자바스크립트] 대문자 기준으로 글자 변환하기 (Convert PascalCase string into snake_case)
    Algorithm 2019. 4. 2. 00:21

    -해당 문제는 codewars사이트의 level5 문제입니다. (1~8단계 중 8단계가 가장 쉬운 레벨)-

     

     

    [문제] Complete the function/method so that it takes CamelCase string and returns the string in snake_case notation. Lowercase characters can be numbers. If method gets number, it should return string. 

    //  returns test_controller
    toUnderscore('TestController');
    
    // returns movies_and_books
    toUnderscore('MoviesAndBooks');
    
    // returns app7_test
    toUnderscore('App7Test');
    
    // returns "1"
    toUnderscore(1);

     

    [해석]

    카멜 케이스 문자를 스네이크 케이스 형태로 바꿔서 리턴하여라. 소문자 대신 숫자가 들어갈 수도 있다. 만약에 숫자가 변수로 들어가면 그 숫자를 string으로 변환하여 리턴하여라.

     


     

     

    이 문제는 2가지 방법으로 풀었는데 첫번째 방법은 매우 복잡하다.

     

    1. 대문자를 구분할 수 있는 정규식 /[A-Z]/g 을 선언한다.
    2. index라는 변수에 0을 담는다.
    3. 이제 문자열에서 index+1의 위치부터 대문자를 찾는다.
    4. 대문자가 나타나면 문자열에서 index위치부터 인덱스+대문자의 위치+1의 위치까지 잘라내서 소문자로 변환한 후  newSt라는 변수에 저장한다. 
    5. 대문자를 찾은 후 index에 upLoca+1을 더해준다. (첫번째 대문자를 찾은 위치 다음부터 다시 대문자를 찾기 위해)
    6. 대문자가 안나올 때까지(upLoca > -1) 반복하여 문자를 찾아서 소문자로 변환 후 '_'와 함께 연결해준다.
    function toUnderscore(string) {
    	if (typeof string == 'number') {
    		return string.toString()
    	}
    
    	var upper = /[A-Z]/g
    	var index = 0;
    	var upLoca = string.substring(index+1).search(upper)
    	var newSt = ''
    	var restWord
    	
    	while(upLoca > -1) {
    		var word = string.substring(index, index+upLoca+1).toLowerCase()
    		if(newSt == '') {
    			newSt += word
    		} else {
    			newSt += '_' + word
    		}
    		
    		index = index + upLoca + 1
    		upLoca = string.substring(index+1).search(upper)
    		restWord = string.substring(index+upLoca+1).toLowerCase()
    	}
    	newSt += '_' + restWord
    	return newSt
    }

     

    이렇게 복잡하게 풀었는데 아니나 다를까

    엄청 간단하게 푼 답변들이 많았다.

     

     

    그래서 다른 사람들의 풀이를 살펴보니 replace()함수를 사용한 풀이가 많이 있었다.

    replace()함수를 MDN에서 검색해보니 내가 전혀 몰랐던 많은 기능을 내장하고 있었다.

     

    아래 함수를 살펴보자!

    function toUnderscore (string) {
    	var result = string.replace(/[A-Z]/g, function(upp, i, st) {
    		console.log(upp, i, st)
    	})
    }
    
    toUnderscore('TestController')
    toUnderscore('MoviesAndBooks')
    toUnderscore('App7Test')

    위 함수를 실행시키면 console창에 다음과 같이 출력된다.

     

    대문자, 그 대문자의 위치 인덱스, 그리고 대상 string

     

    대문자의 위치가 0이면 맨 첫글자라는 뜻이니 0인 경우에는 그냥 소문자로 변환하고

    0보다 큰 경우에는 소문자로 변환한 후 앞에 '_'를 붙여서 return 하면

    대문자가 마법같이 _ + 소문자로 바뀌어서 return된다.

    function toUnderscore (string) {
    	if (typeof string == 'number') {
    		return string.toString()
    	}
    
    	var result = string.replace(/[A-Z]/g, function(upp, i, st) {
    		if(i==0) {
    			return upp.toLowerCase()
    		} else {
    			return '_' + upp.toLowerCase()
    		}
    	})
    	return result
    }

     

    그리고 이제 위의 코드를 아래와 같이 더욱 간단하게 줄일 수 있다.

     

    (참고) 조건식  ?  조건식이 참일 경우  :   조건식이 거짓일 경우

    function toUnderscore (string) {
      	if (typeof string == 'number') {
    		return string.toString()
    	}
    	return string.replace(/[A-Z]/g, function(upp, i, st) {
    		return (i==0 ? '' : '_') + upp.toLowerCase()
    	})
    }

     

    반응형

    COMMENT