자릿수 더하기, 하샤드 수, 핸드폰 번호 가리기

Daisy🌼·2022년 5월 8일
0

자릿수 더하기

문제 링크

나의 풀이

function solution(n){
   return String(n)
         .split("")
         .map((num)=>parseInt(num))
         .reduce((acc, cur)=>acc + cur)
}

다른 풀이

function solution(){
	return (n+"")
      		.split("")
      		.reduce((acc, curr) => acc + parseInt(cur), 0);
}

//참고로 이 풀이는 단항 연산자 +를 활용해 더 간결하게 줄일 수 있습니다.
//return (n + '').split('').reduce((acc, cur)=> +acc + +cur);
  • '나의 풀이'와 비슷하지만, 숫자를 문자열로 바꾸기 위해 이항 연산자 +의 특성을 활용했습니다.

  • JavaScript에서 덧셈 연산자(+)는 덧셈 연산 뿐만 아니라 문자열을 연결하는 기능을 가지고 있습니다. 참고로 연산자 양 옆에 피연산자가 오는 이항 연산자 +일 경우에 해당합니다.(한 개의 피연산자 앞에 오는 +는 단항 연산자 +입니다.)

  • 피연산자가 문자열일 때 문자열을 연결하는데, 이때 피연산자 중 어느 하나가 문자열이 아니라면 문자열로 형변환을 합니다.

  • 문제에서 n + ""에서 n은 숫자, ""(빈 문자열)은 문자열이기 때문에, 문자열이 아닌 n을 문자열로 형변환합니다. 따라서 둘을 합친 결과는 문자열 n이 됩니다.

  • 이러한 이항 연산자 +의 트릭을 이용하면 String()과 같은 함수를 사용하지 않고도 간편하게 형변환을 할 수 있습니다.

하샤드 수

문제 링크

나의 풀이

function solution(x){
	let sum = String(x)
    			.split('')
    			.map(num => parseInt(num))
    			.reduce((acc, cur)=> acc + cur);
  
  return x % sum === 0 ? true : false
}
  • 숫자의 각 자릿수에 해당하는 숫자를 더해야 하기 때문에, 앞서 살펴본 '자릿수 더하기' 문제의 로직을 이용했습니다.

다른 풀이

function solution(x){
      return !(x % String(x).split('').reduce((a, b) => +b + +a ));
}

//참고로 이 풀이는 단항 연산자 +를 활용해 더 간결하게 줄일 수 있습니다.
//return (n + '').split('').reduce((a, b)=> +a + +b);
  • '나의 풀이'보다 훨씬 간단하게 작성된 풀이입니다. split() 메서드를 사용하면 요소들이 문자열 형태로 담기기 때문에, 저는 map()과 parseInt()를 사용해 숫자로 변환한 값을 담은 새로운 배열을 만들었습니다.

  • 반면 이 풀이에서는 단항 연산자 +를 활용해 map()과 parseInt()의 사용을 줄였습니다. 덧셈 연산자(+)는 양 옆에 피연산자가 오는 이항 연산자 +와 피연산자 앞에만 오는 단항 연산자 +로 사용할 수 있습니다.

  • 단항 연산자 +는 피연산자가 숫자가 아니라면 피연산자를 숫자로 형변환합니다.

let one = '1';
let two = '2';

console.log(typeof +one) //number
console.log(typeof +two) //number
  • 이러한 트릭을 사용하면 굳이 반복을 돌리지 않아도 됩니다. 앞선 풀이에서는 map()parseInt()를 사용하지 않고, reduce() 메서드의 콜백함수 부분에서 더하는 값에 단항 연산자 +를 붙여 형변환해준 값으로 연산했습니다.

  • 이렇게 + 연산자의 특성을 사용한 트릭으로 코드를 좀 더 간결하게 작성할 수 있습니다.

⭐️ 덧셈 연산자 트릭 정리

  • 단항 연산자 +: 숫자가 아닌 피연산자를 숫자로 형변환
  • 이항 연산자 +: 문자열이 아닌 피연산자를 문자열로 형변환

핸드폰 번호 가리기

문제 링크

나의 풀이

function solution(phone_number) {
    let length = phone_number.length;
    return "*".repeat(length - 4) + phone_number.slice(length - 4);
}
  • 문자열의 길이 - 4를 기준으로 나뉜다는 점을 활용했습니다.

  • 문자열의 길이 - 4만큼의 개수만큼 *를 반복한 문자열을 만들고, 문자열의 길이 - 4부터 끝까지 즉 나머지 4글자는 slice()를 이용해 잘랐습니다. 마지막으로 두 문자열을 이어 붙였습니다.

다른 풀이

function hide_numbers(s) {
  return s.replace(/\d(?=\d{4})/g, "*");
}
  • 정규표현식을 사용한 방법입니다. (저는 정규표현식을 정말 잘 활용을 못해서 언젠가는 정복을 해야겠다고 다짐만 하고 있습니다...🥲)

✔️ split()을 올바르게 사용하자

  • 문자열의 요소들을 배열에 담을 때 String.split()을 사용할 일이 많은데, 의외로 자주 헷갈려서 정리해봅니다.

  • String.split()메서드를 사용할 때, parameter로는 해당 문자열을 쪼개는 기준을 문자열로 전달해야 합니다. (여기서 제가 사용한 "쪼갠다"는 표현은 MDN 문서의 "구분자"와 동일합니다.😊)

  • 예를 들어 hello wolrd라는 문자열을 helloworld로 쪼갠다면, 공백을 기준으로 쪼개야 합니다. 또한 공백을 문자열 형태로 전달해야 하기 때문에 "hello world".split(' ')이렇게 작성합니다.

let str = 'hello world';
let arr = str.split(' ');

console.log(arr); //['hello', 'world']
  • 또한 parameter로 빈 문자열을 전달하면 각각의 문자열을 배열의 요소에 담습니다. 특히 이렇게 문자 하나하나를 배열의 요소로 만들어야 하는 경우를 많이 접하기 때문에, 빈 문자열을 전달하는 이 방식을 알아두면 상당히 유용할 것 같습니다.
let str = 'hello world';
let arr = str.split('');

console.log(arr); //['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
  • 마지막으로, 아무것도 전달하지 않으면 해당 문자열을 배열의 유일한 요소로 갖습니다. 즉 문자열을 통째로 배열에 담는다고 생각할 수 있습니다.
let str = 'hello world';
let arr = str.split();

console.log(arr); //['hello world']
  • 저는 parameter가 빈 문자열일 때와 생략했을 때를 헷갈렸습니다. '12345'라는 문자열 각각의 숫자를 배열에 담고 싶었는데, 아무리 해도 결과는 ['12345'] 처럼 나왔습니다. paramter에 빈 문자열이 아니라 아예 아무 것도 전달하지 않아서 생긴 문제였습니다.

⭐️ split()메서드 3줄 정리

  • split(' '): 공백을 기준으로 문자열을 쪼개서 배열에 담습니다.
  • split(''): 각각의 문자열로 쪼개서 배열에 담습니다.
  • split(): 해당 문자열을 통째로 배열에 담습니다.

✔️ join도 올바르게 사용하자

  • split()과 완전히 반대되는 기능을 수행하는 join() 역시 비슷하게 활용할 수 있습니다. join()은 배열의 요소들을 합쳐서 문자열로 반환하는데 이때는 합치는 기준을 문자열로 전달합니다.

⭐️ join()메서드 3줄 정리

  • join(' '): 공백을 붙여 배열의 요소들을 합칩니다.
  • join(''): 붙이는 기준 없이 하나로 합칩니다.
  • join(): 배열 내부의 쉼표까지 붙여 합칩니다.

✔️ toString()와 String()의 차이

  • 숫자 n을 문자열로 변환할 때, 어떤 것을 사용해야 하는지 헷갈렸습니다. 결과적으로는 거의 차이가 없다고 합니다.

  • 차이가 있다면 toString()은 메서드이고 String()은 생성자 즉 함수라고 부른다 것과, toString()은 값이 undefined 또는 null일 때 TypeError가 발생하지만 String()은 문제없이 문자열로 변환한다는 점이라고 합니다. (출처: What's the difference between String(value) vs value.toString)

  • 다행히 이를 활용한 문제에서는 input으로 들어오는 값으로 undefined 또는 null이 주어지지 않는다는 것을 확신하기 때문에 둘 다 사용해도 상관없을 것 같습니다. 아마 편한 것을 쓰면 되지 않을까 싶습니다.🧐


참고 자료

profile
커피와 재즈를 좋아하는 코린이 | 좋은 글 좋은 코드를 쓰고 싶습니다

0개의 댓글