View
들어가기 전에
프로그래머스 코딩 테스트 0 레벨이 생겼다.
1 레벨을 풀고 있었지만 아무래도 기초가 부족하다 느껴져 0 레벨을 다 풀어보고자 차근차근 풀고 있다.
0 레벨 문제는 총 100개로 구성되어있고 생각보다 간단한 문제들이 많아서 기초를 다지기에 제격이라고 느껴진다.
그렇게 한 문제씩 풀어나가던 도중 내 답안에서 궁금점이 생겨 글을 남긴다.
궁금증이 생긴 문제
자릿수 더하기
정수 n이 매개변수로 주어질 때 n의 각 자리 숫자의 합을 retrun 하도록 solution 함수를 완성해주세요.
첫 번째로 시도한 방법
function solution(n) {
return n
.toString()
.split('')
.reduce((a, b) => Number(a) + Number(b))
}
이렇게 하니 테스트 케이스 중 한 개가 실패가 떴다.
두 번째로 시도한 방법
function solution(n) {
return n
.toString()
.split('')
.map(v => +v)
.reduce((a ,b) => a + b)
}
형 변환이 문제인가 싶어서 중간에 map을 추가해 모두 숫자 타입으로 바꾼 뒤 reduce를 해줬다.
그렇게 해서 문제를 통과했고 다른 사람들의 답을 보던 중 reduce에 대해 몰랐던 사실을 알게 됐다.
다른 사람의 답.
function solution(n) {
return n
.toString()
.split("")
.reduce((acc, cur) => acc + Number(cur), 0);
}
reduce의 두 번째 인자로 초기값을 넣어줄 수 있는데 그 초기값을 넣어주지 않으면
배열의 첫 번째 값이 들어간다.
참고 mdn문서
앞선 첫 번째로 시도한 방법에서는 초기값을 넣어주지 않았기 때문에 모든 배열의 인덱스를 돌지 못해 실패를 했다고 생각했다.
그렇다면 두 번째로 시도한 방법에서는 왜 성공한 걸까?
똑같이 초기값을 넣어주지 않았는데도 성공한 이유가 궁금했다.
원인을 찾다
빈 배열일 경우
첫 번째로 생각해 본 것은 빈 배열일 경우다.

빈 배열에서 reduce를 사용할 경우 TypeError가 난다.
하지만 빈 배열일 경우... 는 아마도 없을 것 같아서 다른 것을 생각해봤다.
한 자릿수의 숫자일 경우
만약 입력받는 숫자가 한 자릿수의 숫자일 경우에는 reduce에 초기값이 없을 경우 실행되지 않았다.
function solution(n) {
return n
.toString()
.split('')
.reduce((a ,b) => Number(a) + Number(b))
}

테스트 케이스에 0을 추가한 후 실행해보니 '0'이라는 값이 출력됐다.
reduce의 콜백 함수에 현재 값과 누적 값을 넣어 계산하도록 해놨는데 다음 값이 없기 때문에 실행되지 않은 것 같다.
그래서 더해줄 숫자가 없기때문에 형 변환이 되지 않고 문자열을 리턴해서 실패가 났던 거다.

초기값을 넣어주면 숫자 타입으로 잘 변환돼서 작동한다.
마찬가지로 내가 통과했던 두 번째 답안을 다시 보면
function solution(n) {
return n
.toString()
.split('')
.map(v => +v)
.reduce((a ,b) => a + b)
}
reduce에 초기값이 없지만 map으로 형 변환을 해주었기 때문에
계산될 값이 없어도 숫자 타입의 값이 리턴되므로 통과할 수 있었다.
결론
자바스크립트로 연산을 할 땐 리턴 타입이 어떻게 나오는지 꼭 확인하자!
그리고 꼭 생각한 대로 작동 안 할 수도 있다는 것을 명심하자 ㅋㅋ
글의 제목에 reduce는 숫자가 없어도 에러가 나지 않아...라고 한 이유는
콜백 함수에 인자를 두 개 받도록 되어있는데 들어오는 인자 값이 하나뿐인데도 실행되는 게 어이없어서 그랬다 ㅠ

오늘도 평화로운 자스의 세계
'FRONT-END > JavaScript' 카테고리의 다른 글
| append / appendChild 차이점 (0) | 2022.05.12 |
|---|---|
| 배열 메서드 정리 한번에 해보자 (0) | 2022.05.11 |
| Variable(변수) (0) | 2022.04.28 |