Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript: 문자열에서 각 단어의 첫 글자를 대문자로 바꾸는 3가지 방법

초보자에게 적합한 코딩 챌린지 중에는 엔지니어처럼 사고하는 법을 익히는 데 큰 도움이 되는 것들이 많습니다. 그중 하나가 바로 주어진 문자열에서 모든 단어의 첫 글자를 대문자로 바꾸는 문제입니다. 이 글에서는 문제의 요구사항과 함께 JavaScript로 풀 수 있는 여러 가지 방법을 살펴보겠습니다.

문제 소개

capitalize 함수가 str을 매개변수로 받으면, 모든 단어의 첫 글자가 대문자로 변환된 str을 반환해야 합니다. 풀이 과정에서 엣지 케이스(입력값이 없는 경우, 잘못된 타입의 입력 등)도 함께 고려해 보세요.

접근 방법

  1. 문제를 다시 한번 읽고, 문장 속에서 핵심 키워드를 적어두거나 표시하세요.
  2. 문제의 의미를 조합해 전체 그림을 이해하세요. 코딩 챌린지에서 가장 어려운 부분 중 하나는 문제가 무엇을 요구하는지 파악하는 것입니다. 문제를 정확히 이해하면 해결의 절반은 끝난 것이나 다름없습니다.
  3. 가능한 해결책을 의사코드(pseudocode)로 작성해 보세요. 실제 실행 가능한 코드일 필요는 없습니다. IDE나 브라우저 콘솔에서 돌아갈 필요 없이 일반 문장으로 작성해도 충분합니다:
주어진 것 이해하기:
	함수가 하나 주어짐
 	어떤 형태의 입력을 받음

반환해야 할 것 이해하기:
 	문자열
가장 먼저 해야 할 일은 무엇일까?
입력이 문자열이라는 걸 알 때 어떤 선택지가 있을까?
활용할 수 있는 문자열 메서드가 있을까?
모르겠다면 어떻게 찾아볼 수 있을까?
입력이 비어 있거나 숫자, 객체라면 어떻게 처리할까?
일단 for 루프를 작성해 문자열을 순회하는 것부터 시작해 보자.
 		그다음은? ... 이런 식으로 계속...

문제를 단계별로 철저하게 분해해 보세요. 이 과정은 엣지 케이스 — 잘못된 입력이 전달되거나 빈 문자열이 들어오는 경우 — 를 떠올리고, 문제를 논리적인 단계로 나누는 방법을 고민하는 데 큰 도움이 됩니다. 이는 일종의 실험 단계로, 정답이 없습니다. 문제에 접근하는 방법에 대한 생각만 있으면 충분합니다. 그 생각이 엉뚱한 방향일 수도 있지만, 그렇기 때문에 어떤 접근이 작동하지 않는지 배울 수 있습니다.

저는 문제를 소리 내어 설명하며 분해하면 로직이 더 쉽게 떠오른다는 것을 경험했습니다. 사람마다 맞는 방식은 다르겠지만, 여러분에게도 도움이 될 수 있으니 한번 시도해 보시길 권합니다! 이렇게 작은 문제에 의사코드를 작성하는 게 다소 과해 보일 수 있지만, 지금 이 습관을 들여 두면 훨씬 어려운 문제를 만났을 때 훨씬 수월해질 것입니다.

해결 방법

방법 1: split()과 for 루프, replace(), charAt() 메서드 활용

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width">
   <title>for loop</title>
 
 </head>
 <body>
   <div id="root"></div>
  <script async defer>
    let capitalize = (str) => {
      let arr = str.split(' ');
      for(let i = 0; i < arr.length; i++ ) {
         arr[i] = arr[i].replace(arr[i].charAt(0),  arr[i].charAt(0).toUpperCase());
     }
     return arr.join(' ');
   }
   let root = document.getElementById('root');
   root.innerHTML = JSON.stringify(capitalize('the quick brown fox jumped over the lazy dog'));
  </script>
 </body>
</html>

첫 번째 방법에서는 문자열을 공백을 기준으로 분리(split)합니다. 그러면 각 단어가 개별 인덱스에 담긴 배열(arr)이 만들어집니다. 배열을 순회하면서 각 단어의 개별 문자에 접근할 수 있습니다. 인덱스 i에 해당하는 문자열(arr[i])을, 0번째 문자(arr[i].charAt(0))를 대문자로 바꾼 결과로 재할당합니다. 마지막으로 join 메서드로 배열을 다시 공백으로 연결된 하나의 문자열로 합쳐 반환합니다.

방법 2: split()과 map 메서드, slice() 활용

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width">
   <title>Map</title>
 </head>
 <body>
   <div id="root"></div>
  <script async defer>
    let capitalize = (str) => {
      // 공백을 기준으로 문자열을 분리해 다룰 대상을 파악합니다.
      let arr = str.split(' ') // 따옴표 사이에 반드시 공백이 있어야 합니다.
      // map 메서드를 사용합니다.
      arr.map((word, index, array) => {
        array[index] = array[index][0].toUpperCase() + array[index].slice(1);
        return array[index];
 
      })
      console.log(arr)
      return arr.join(' ');
    }
   let root = document.getElementById('root');
   root.innerHTML = JSON.stringify(capitalize('the quick brown fox jumped over the lazy dog'));
   </script>
 </body>
</html>

이 방법 역시 시작점은 비슷하지만, 이후에는 ES6 배열 메서드인 map을 사용해 배열을 순회하며 각 단어의 첫 글자를 대문자로 변환한 새 값을 만듭니다. 첫 글자에는 toUpperCase() 메서드를, 나머지 부분에는 slice() 메서드를 적용하고, 문자열 연결(concatenation)로 새로운 단어를 완성합니다. 그다음 배열을 join하여 반환합니다.

방법 3: 정규표현식(regular expression) 활용

<!DOCTYPE html>
<html>
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width">
   <title>repl.it</title>
 
 </head>
 <body>
   <div id="root"></div>
  <script async defer>
    let capitalize = (str) => {
      let regex = /(^|\s)\S/g
       return str.replace(regex, letter => letter.toUpperCase());
    }
   let root = document.getElementById('root');
   root.innerHTML = JSON.stringify(capitalize('the quick brown fox jumped over the lazy dog'));
   </script>
 </body>
</html>

이 방법에서는 정규표현식을 사용해 문자열의 시작(^) 또는 공백 문자(\s) 바로 뒤에 오는 모든 비공백 문자(\S)를 찾아냅니다. 패턴 끝의 g 플래그는 전역(global) 검색을 의미하며, 패턴과 일치하는 모든 항목을 찾을 수 있게 해줍니다. 이후 replace 메서드로 해당 패턴을, 일치한 글자를 대문자로 반환하는 함수로 교체합니다.

마무리하며

위에서 소개한 방법들이 이 문제의 유일한 해결책은 아닙니다. 이런 유형의 문제를 계속 풀다 보면 글이나 블로그에서 제시하는 것과 같거나, 혹은 전혀 다른 자신만의 해결책을 찾게 될 것입니다. 그것은 좋은 신호입니다. 여러분이 엔지니어처럼 생각하기 시작했다는 뜻이고, 그것이 바로 목표이기 때문입니다.

부트캠프 참가자의 81%가 수료 후 기술 직군 취업 전망에 대해 더 자신감을 느꼈다고 답했습니다. 지금 바로 자신에게 맞는 부트캠프를 찾아보세요.

부트캠프 졸업생은 평균적으로 부트캠프를 시작한 시점부터 첫 직장에 입사하기까지 6개월 이내의 짧은 기간 동안 커리어 전환을 완료했습니다.

포기하지 말고 계속 도전하세요. 위의 해결책들은 엣지 케이스를 처리하지 않았습니다. 인수가 빈 문자열이거나 숫자라면 어떻게 해야 할까요? 위 코드에 엣지 케이스 처리 로직을 직접 추가해 보세요.

힌트: 느낌표(bang, !)를 활용해 str이 존재하는지 조건문으로 확인해 보세요. 또한 MDN 문서를 참고하면, 타입을 알 수 없는 값의 타입을 확인하는 메서드를 찾을 수 있습니다.

한 가지 더: 아직 도전하지 않았다면 JavaScript 문자열 뒤집기(String Reverse) 코드 챌린지에도 도전해 보세요!

추가로 참고할 만한 자료 

Ruby에서 정규표현식 사용하기 – Ruby 전용 글이지만, 정규표현식은 대체로 언어에 독립적입니다. 방법 3의 RegExp 문법을 더 깊이 이해하고 싶다면 확인해 보세요. 

JavaScript Replace Text: 단계별 가이드 – 방법 1에서 사용된 replace 메서드를 집중적으로 다루는 튜토리얼입니다.