Create Phone Number<6 kyu>

jjanmo·2020년 1월 3일
0

Codewars에서 뒹굴기

목록 보기
11/32

문제링크

문제

Write a function that accepts an array of 10 integers (between 0 and 9), that returns a string of those numbers in the form of a phone number.

  • Example:
    createPhoneNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]) // => returns "(123) 456-7890"

  • The returned format must be correct in order to complete this challenge.

  • Don't forget the space after the closing parentheses!

🚩 문제해석
실제로 많이 사용될 수 있는 문제이다. 주어진 숫자 배열을 전화번호 형식으로 바꾸는 문제이다. 주어진 배열을 example에서 보여준 형식으로 만들어주면 된다.

문제접근

  • 첫번째 생각 : 주어진 배열을 3개,4개,4개로 잘라서 사이 사이에 (, ), ' ' 을 넣어주면 되지 않을까?

  • 두번째 생각 : 어라? 배열이 주어졌네?! 그리고 하나의 값을 원하네?! 그러면 reduce()로도 할 수 있을거 같은데...

결국 코드는 두번째 생각으로 만들었다. 어떤 힌트를 얻지 않고 스스로 생각해서 reduce()라는 메소드를 사용해보고 싶었다.

function createPhoneNumber(numbers){
  return numbers.reduce(function(a, v, i){ //(누적값, 현재값, 현재인덱스)
    if(i === 0){
      return a + '(' + v;
    }
    else if(i === 2){
      return a + v + ') ';
    }
    else if(i === 5){
      return a + v + '-';
    }
    else return a + v;
  },'');
}

뭔가 아쉽다. 그런데 무엇 때문인지는 잘모르겠다. 잘 사용한 것 같은데 뭔가 지금까지 봐왔던 reduce()와는 느낌이 다르다. 왜일까? 아직은 답이 나오지 않는다.

Best Solution

몇가지 풀이를 포스팅 해봤다.

  • 첫번째 풀이
function createPhoneNumber(numbers){
  numbers = numbers.join('');
  return '(' + numbers.substring(0, 3) + ') ' 
      + numbers.substring(3, 6) 
      + '-' 
      + numbers.substring(6);
}

나의 첫번째 생각과 비슷하게 구현해 놓았다. 다 해 놓고보니 reduce()보다 풀이가 더 좋은 것 같다. 또 위 풀이를 더 직관적으로 보이게 하려면 이렇게도 할 수 있을 것 같다.

return `(${numbers.substring(0, 3)}) ${numbers.substring(3, 6)}-${numbers.substring(6)}`;

return 부분만 template literals를 사용해서 더 직관으로 보일 수 있다.

  • 두번째 풀이
function createPhoneNumber(numbers){
  var format = "(xxx) xxx-xxxx";
  for(var i = 0; i < numbers.length; i++) {
    format = format.replace('x', numbers[i]);
  }
  return format;
}

칭찬 일색인 풀이였다. 만약에 번호의 형식을 바꾸고 싶다면 전체적인 틀이 아니라 format이라고 하는 문자열의 모양만 바꿔주면 된다. 사실 이와 같은 풀이는 이 전에도 한번 본 적이 있다. 정해진 상수값이나 형식같은 것은 상수화시켜서 사용하는게 좋네 라고 그 때는 생각했지만, 이 문제를 보고 그렇게 생각하지 못한 것은 어쩔 수 없는 것 같다. 지속적인 생각의 연습이 필요하다고 느껴진다. 보고 깨닫고(?) 잊어버리고 깨닫고(?) 잊어버리기를 반복하다보면 무엇이됐든 언제간 체화될 것이라 믿는다.

갑자기 우리 이고잉 형님(😁) 께서 이런 말씀을 해주신게 생각난다. 배우고 익히고 잊어버려라!

  • replace()에 대해서
    • syntax : str.replace(바꾸고자하는 문자열, 집어넣을 문자열); 바꾸고자하는 문자열에는 정규표현식도 가능하다.
    • 동작 방식 : 바꾸고자하는 문자열을 찾아서 그 문자열을 집어넣을 문자열로 교체한다. 첫 번째 일치되는 문자열만이 교체된다.(자바스크립트에는 replaceAll()과 같은 문자열 전체에서 교체하는 메소드가 존재하지 않는다.)
  • 세번째 풀이
function createPhoneNumber(numbers){
   return numbers.reduce((p,c) => p.replace('x',c), "(xxx) xxx-xxxx");
}

사실 이 풀이가 두번째 풀이보다 더 기발한 아이디어를 가진 것이 아닌가 생각된다. 하지만 위의 코드보다 읽기 불편하다라는 느낌이 든다. 그래서 아마 평가를 잘 받지 못한 것 같다. 이건 개인적인 생각이지만, 세번째 풀이를 한 사람도 두번째 풀이를 먼저 보고나서 업그레이드를 시킨 것이 아닐까. 초기값을 저렇게 주어서 변형시킬 수 있다는 것이 CLEVER하다.

결론

이번 문제는 위의 풀이 말고도 정규표현식을 이용한 풀이가 참 많았다. 그리고 자바스크립트에서 지원하지않는 replaceAll() 같은 메소드를 정규표현식을 이용해서 만들수 있다고 알고 있다. 사실 난 아직 정규표현식에 대해서 익숙하지 못하다. 어딘가에서 들었는데 중급이상의 개발자로 성장하기 위해선 정규표현식을 잘 활용할 줄 알아야 한다고 한다. 정규표현식을 정리할 기회를 갖도록 하자.

참고

MDN String.prototype.replace()

🚀 문제를 풀어나갈 때 생각의 흐름을 정리합니다. 또한 새로운 풀이에 대한 코드를 분석하고 모르는 부분에 대해서 정리합니다. 다른 의견은 언제나 환영합니다. 틀린 내용에 대한 피드백 또한 항상 감사합니다.

profile
눈길을 걸어갈 때 어지럽게 걷지 말기를.

0개의 댓글