문제)
- 입력한 숫자까지의 소수를 아래 사진과 같이 출력하는 기능을 만들어라.
- 1 이하를 입력한다면 1 이상의 수를 입력하라고 경고창을 출력해라.
풀이 전 생각)
- 소수를 판별하는 함수를 만들어야 한다.
- start 버튼을누르면 입력한 수부터 소수인지 아닌지를 모두 다 판단해야 한다.
- start 버튼을 누른 뒤 화면에 출력하려면 innerHTML 또는 innerText로 어떤 결과값을 산출해야 한다.
- 함수 작성은 함수 작동의 행위가 시작되는 onclick 프로퍼티로부터 작성한다.
- 그 외, 모르는 부분이나 수정해야할 부분은 작성하면서 세분화한다.
<input class="input" type="number">
<button class="button">Start</button>
<div class="display"></div>
<script>
const display = document.querySelector('.display')
const input = document.querySelector('.input')
const button = document.querySelector('.button')
isPrime = (num, i = 2) => {
if (num < 2) return false
if (num === i) return true
if (num % i === 0) return false
return isPrime(num, i + 1)
}
getPrime = (start, i = 1, result = "") => {
if (start < i) {
return result
}
if (isPrime(i)) {
return getPrime(start, i + 1, result + `<h1>${i}</h1>`)
}
return getPrime(start, i + 1, result)
}
button.onclick = () => {
const start = +input.value
if (start < 2) {
return alert('2보다 큰 값을 입력하세요.')
}
const result = getPrime(start)
display.innerHTML = result
}
/* 아래는 함수 쓰기 전 미리 작성해놓은 블루프린트임. */
// 소수를 판별하는 식을 만들어야 함.
// Start 버튼을 누르면 입력한 수부터 소수인지 아닌 수를 파악해야함
// Start 버튼을 누른 뒤 소수들이 화면에 나오기 위해서는
// button.onclick은 어떠한 값을 return 해야함.(틀린 생각이었음.)
// 그 리턴값은 innerHTML이 되고 <h1>으로 끼워넣어져야함.
</script>
위 기능의 동작 순서)
각 종 html 요소들을 querySelector로 지정하여, 선택가능한 프로퍼티로 만든다.
button.onclick 프로퍼티를 클릭하면 input의 입력값을 비교한 뒤
result 값을 getPrime 함수를 이용해 받아낸다.
그리고 innerHTML 기능을 통해 출력한다.
이제 getPrime 함수를 작성한다.
getPrime 함수는 처음 받은 숫자가 소수인지 아닌지 판별하고,
소수라면 그 값을 텍스트화 하는 함수이다.
소수인지 아닌지 판별을 하기 위해서는 별도의 함수가 필요하다.
따라서 isPrime 함수를 만든다.
isPrime함수는 받은 숫자가 소수인지 아닌지만 판단한다.
isPrime이 true이면(소수이면) getPrime의 인덱스는 하나씩 올라가고 소수값을 텍스트로 저장한다.
false이면 getPrime의 인덱스를 1만 더한 뒤 재귀시킨다.
올라가는 인덱스는 isPrime의 num에 해당하고,
getPrime의 start(초기 입력받은 값)과 i가 같아지면 result를 반환한다.
최종적으로 result를 리턴하면 onclick의 result는 소수들이 모인 텍스트를 가지게 되고
이것이 innerHTML에 출력된다.
코드 리팩토링)
<input class="input" type="number">
<button class="button">Start</button>
<div class="display"></div>
<script>
const display = document.querySelector('.display')
const input = document.querySelector('.input')
const button = document.querySelector('.button')
isPrime = (num, i = 2) => {
if (num < 2) return false
if (num === i) return true
if (num % i === 0) return false
return isPrime(num, i + 1)
}
getPrime = (start, i = 1, result = "") => {
if (start < i) {
return result
}
if (isPrime(i)) {
result = result + `<h1>${i}</h1>` // 이 부분 수정
}
return getPrime(start, i + 1, result)
}
button.onclick = () => {
const start = +input.value
if (start < 2) {
return alert('2보다 큰 값을 입력하세요.')
}
display.innerHTML = getPrime(start) // 이 부분 수정
}
</script>
1. 반복되는 두개의 return을 쓸 필요는 없기에 result를 별도로 떼어놓고 return을 적게 유지할 수 있다.
2. 굳이 변수를 사용하지 않고도 바로 값을 출력할 수 있다. 하지만 이 경우, 코드의 가독성을 해칠 수 있다.
두 개의 리팩토링은 연산수를 크게 감소시키지는 않으나, 가독성을 좋게한다고 생각할 수 있다.
'Javascript' 카테고리의 다른 글
배열 연습 (0) | 2022.08.10 |
---|---|
Chat input + delay typing (0) | 2022.08.09 |
Closure UI (덧셈 Closure 활용) (0) | 2022.08.05 |
소수 생성기 (0) | 2022.08.04 |
소수(Prime number) 구하기 및 jest를 이용한 테스트 케이스 작성 (0) | 2022.08.04 |