중복X , 무작위로 숫자를 뽑기 - (로또 추첨기와 비슷한 원리)
먼저 Math.random 메서드 이용한다.
0 <= Math.random < 1
0 <= Math.random * 9 < 9
1 <= Math.random * 9 + 1 < 10
const numbers = [];
for (let n = 1; n <= 9; n++) {
numbers.push(n);
}
const answer = [];
for (let n = 0; n < 4; n++) { // 네 번 반복
const index = Math.floor(Math.random() * number.length); // 0 ~ 8
answer.push(numbers[index]);
numbers.splice(index, 1);
}
answer 이라는 빈 배열을 만들고, numbers 배열로부터 숫자를 하나씩 꺼내는 원리를 생각한다.
index 를 무작위로 뽑고, numbers[index] 로 실제 숫자를 가져오자.
여기서 중복을 제거하는 방법은 numbers 배열에서 실제 숫자를 가져올 뿐만 아니라 숫자가 있던 자리를 제거해야 한다. 그래야 중복이 되지 않는다. 따라서 splice 메서드를 이용하게 된다.
splice(배열의 변경을 시작할 인덱스, 배열에서 제거할 요소의 수, 배열에 추가할 요소)
form 에는 submit 이라는 이벤트가 있다.
$form.addEventListner('submit', );
form 에 있는 버튼 클릭, 혹은 엔터를 누르면 submit 이 호출이 된다.
실제로 버튼을 누르고 console.log 해보면 잠깐 떴다가 사라지는 것을 볼 수 있다. 그리고 url 뒤에 ?가 붙는다. 새로고침 현상이 보이는데 form은 서버로 전송되고 다시 돌려 받는 기본적인 동작이 인 것이다. 그래서 화면이 깜빡거리는 것이다.
새로고침되면 변수 같은 것들이 저장된 것들이 날라가므로 event.preventDefault( ) 이용한다.
입력값 검증하기
let tries = [];
function checkInput(input) {
/* < 입력값 검증하기 >
* 1. 4자리 수인가
* 2. 중복된 숫자가 있는가
* 3. 이미 시도한 값인가(!)
*/
if (input.length !== 4) { // 길이는 4가 아닌가
return alert('please typing 4 number');
}
if (new Set(input).size !== 4) { // 중복된 숫자가 있는가
return alert('There are duplicate numbers');
}
if (tries.includes(input)) { // 이미 시도한 값은 아닌가
return alert('already tried');
}
tries.push(input);
}
Set 은 중복을 허용하지 않는 특수한 배열
new 는 예약어인데 10장에서 설명
new Set('1231') 을 하면 Set 내부에는 1,2,3 만 들어간다. 이를 통해 Set 의 요소 개수를 세면 중복된 값이 있는지 아닌지를 검사할 수 있다. 그리고 Set 의 요소 개수를 구할 때는 length 가 아니라 size 를 사용한다.
includes() 메서드는 배열이 특정 요소를 포함하고 있는지 판별
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// expected output: true
join : 배열 -> 문자
split : 문자-> 배열
[3, 1, 3, 6] . join()
-> "3, 1, 3, 6"
[3, 1, 3, 6] . join('')
-> "3136"
[3, 1, 3, 6] . join(':')
->"3 : 1 : 3 : 6"
'3136'. split()
-> ["3136"]
'3136'. split('')
-> (4) ['3', '1', '4', '6']
'3136'. split('1')
->['3', '36']
내가 생각한 숫자야구 코드
let ball = 0;
let strike = 0;
for(i=0; i<4; i++){
for(j=0; j<4; j++){
if(answer[i] === input[j]){
ball++;
if(i===j){
ball--;
strike++;
}
}
}
}
강사님 코드
let ball = 0;
let strike = 0;
for (let i = 0; i < answer.length; i++) {
const index = input.indexOf(answer[i]);
if (index > -1) { // 일치하는 숫자 발견
if (index === i) {
strike++;
}
else {
ball++;
}
}
}
$logs.append(`${strike} strike, ${ball} ball`, document.createElement('br'));
return;
indexOf 와 includes 는 배열이나 문자열에 원하는 값이 들어 있는지 찾는 메서드이다. 원하는 값이 들어 있다면 해당 인덱스를 알려주고 들어있지 않다면 -1을 반환한다. includes 는 조금 더 직관적으로 true/false 를 반환한다.
indexOf 함수는, 문자열(string)에서 특정 문자열(searchvalue)을 찾고,
검색된 문자열이 '첫번째'로 나타나는 위치 index를 리턴합니다.
append 와 appendChild 차이
document.createElement, document.createTextNode 로 만든 태그나 텍스트를 선택한 태그의 자식 태그로 넣는다. appendChild 로는 하나만 넣을 수 있고, append 를 사용하면 여러 개를 동시에 넣을 수 있다. 또한 append 로 텍스트를 추가할 때는 document.createTextNode 대신 문자열을 바로 넣어도 된다.
$logs.append(document.createTextNode('패배'))
$logs.append('패배')
$logs.append(document.createElement('br'))
$logs.innerHTML = $logs.textContent + '<br/>홈런';
이 장에서 사용한 for 문 외에 배열에서도 반복문 역할을 하는 메서드들이 있다. 대표적으로 forEach 가 있다. 몇 스트라이크 몇 볼인지 검사하는 부분을 forEach 메서드로 바꿔 작성할 수 있다.
answer.forEach ( ( ) => { } )
forEach 메서드는 인수 자리에 함수를 넣어주어야 한다.
answer.forEach ( (element, index ) => { } )
--> 요소 하나하나에 함수를 실행해준다.
만약
const answer = [3, 1, 4, 6];
answer.forEach((3,0) ... 이렇게 네번 실행된다.
forEach 메서드는 위 강사님 코드를 이렇게 바꿔쓸 수 있다.
answer.forEach((element, i) => {
const index = input.indexOf(element);
if(index > -1) {
if(index === i){
strike++;
}
else {
ball++;
}
}
})
forEach 를 통해 배열을 바꿀 수는 없다. ---> map 메서드를 생각해보는게 좋다.
const array = [1, 2, 3, 4];
array.map((element, i) => {
return element * 2;
})
// console.log(array); <---- [1, 2, 3, 4]
map 도 반복문의 역할을 하지만, 반환값이 있다는 점에서 forEach 와 다릅니다. map 은 기존 배열의 요소를 일대일로 다른 값으로 바꿉니다. 단, 기존 배열의 값이 바뀌는 것이 아니라 새로운 배열을 만듭니다.
< fill 메서드 >
빈 배열 만들때
Array(9) --> 빈자리 9개
Array(9).fill() --> undefiend가 9개
Array(9).fill(0) --> 0 이 9개
Array(9).fill(0).map((el, idx) => {
return idx + 1;
})
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
6 장에 배울 "로또 추첨기"를 map 메서드를 통해 1 - 45 까지 숫자를 이렇게 만들 수 있다.
순서도 복습 & 정리
숫자 야구를 만들어보고 느낀 점
자바스크립트의 배열 메서드가 익숙하지 않았다. 개념을 계속 봐서 숙지를 해야겠다는 생각이 들었다.
그리고 항상 느끼는거지만 공책에 절차를 자세히 쓰도록 하자. (머릿속대로 코딩하다가 더 시간이 걸림을 깨달았다.)
'🤹🏻♀️ Javascript' 카테고리의 다른 글
제로초 자바스크립트 7장 (가위바위보) (0) | 2021.10.24 |
---|---|
제로초 자바스크립트 6장 (로또 추첨기) (0) | 2021.10.23 |
제로초 자바스크립트 4장 (계산기) (0) | 2021.10.18 |
제로초 자바스크립트 3장 (쿵쿵따) (0) | 2021.10.15 |
preventDefault() (0) | 2021.10.10 |