Front-end/Js

Js 기초(set, map)- AWS 풀스택 과정 20일차

awspspgh 2024. 8. 9. 18:29

오늘은 set, map에 대해서 배워보도록 하겠습니다

 

1. 데이터 구조화
2. 정규 표현식
3. set & map
4. 예제 문제
5. 느낀 점

 

1. 데이터 구조화

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        많은 양의 데이터가 실시간으로 전달되어야할 때 가장 효율적으로
        데이터를 보내는 방법
        데이터 구조화 => 구조화된 텍스트 => JSON
    </h1>
    <ul>
        <li>
            JSON(JavaSript Object Notation)
            javaScript 객체를 구조화된 데이터로 표현하기 위한 문자 기반 표준 포멧
        </li>
        <li>
            웹 서버 (<->) 화면 간에 데이터를 전송할 때 일반적으로 사용되는 데이터 포멧
        </li>
        <li>
            자바스크립트의 객체 형식이기 떄문에, 구조파악이 쉽고 제작도 쉽다.
        </li>
        <li>
            특히 웹 분야는 자바 스크립트가 모든 프론트에 호환된다는 점을 활용
            데이터 수집, 출력, 활용 거의 모든 플랫폼에서 JSON을 활용하고 있음.
        </li>
    </ul>
    <script>
        // https://finance.naver.com/ 거래상위 종목
        const top = {
            '거래상위' : [
                {
                    name: 'KODEX 200 선물인버스',
                    price: 2190,
                    updown: -65,
                    ratio: -2.88
                },
                {
                    name: '우리바이오',
                    price: 5420,
                    updown: 140,
                    ratio: 2.65
                },
                {
                    name: 'SG세계물산',
                    price: 485,
                    updown: -4,
                    ratio: -40.82
                }, {}, {}, {}
            ],
            '상승' : [
                {}, {}, {}
            ],
            '하락' : [
                {}, {}, {}
            ],
            '시가총액상위' : [
                {}, {}, {}
            ]
        };
        // 환율 / 금시세 구조화 해보괴
        const exs = {
            exchange:[
            {
                name: `달러 / 일본 엔(08.08)`,
                price: 147.2600,
                updown: -0.04
            },
            {
                name: `유로 / 달러(08.08)`,
                price: 1.0906,
                updown: -0.00
            },
            {
                name: `파운드 / 달러(08.08)`,
                price: 1.2714,
                updown: -0.00
            },
            {
                name: `달러인덱스(08.08)`,
                price: 103.0200,
                updown: 0.03
            }
        ],
            gold: [
            {
                name: `국제금(08.08)`,
                price: 2463.30,
                updown: 30.90
            },
            {
                name: `국내금(08.08)`,
                price: 107233.97,
                updown: 188.80
            },  
        ]
        }
    </script>
</body>
</html>

 

2. 정규 표현식

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        정규 표현식(Regular Expression)
        문자 내에서 특정 내용을 찾거나 대체, 발췌하는데 사용
    </h1>
    <ul>
        <li>
            RegExp() : 객체로 사용
        </li>
        <li>
            특정 데이터를 탐색, 확인, 존재 여부를 쉽게 파악하기 위한 규칙
        </li>
        <li>
            웹 분야에서는 password, 첨부파일 규칙 등에 사용
            자주 쓰이지는 않음.
        </li>
        <li>
            데이터 분석 관련되어서는 꼭 알고 있어야하는 규칙
        </li>
        <li>
            다른 언어에서도 비슷한 형식으로 쓰이고 있음.
        </li>
    </ul>
    <ul>
        <li>
            /regExp/ : / / => 시작 기호, 종료 기호
            regExp : 패턴   ig : flag(옵션)
        </li>
        <li>
            ('str').match(/regExp/flag)
            str에서 매칭되는 항목들을 배열로 리턴
        </li>
        <li>
            ('str').replace(/regExp/flag, 바꿀 문자)
            str에서 매칭되는 항목들을 바꿈
        </li>
        <li>
            ('str').split(/regExp/)
            정규 표현식에 매칭되는 항목으로 쪼개 배열로 리턴
        </li>
        <li>
            (/regExp/).test('str') : 문자열이 정규표현식에 맞는지 체크
            return true / false
        </li>
    </ul>
    <ul>
        <li>
            정규표현식 플래그
        </li>
        <li>
            i : 대소문자 구분 X, g : 전역 검색, m : 줄바꿈 포함
        </li>
        <li>
            ㄱ-ㅎ가-힇 : 한글 / a-zA-Z : 영문자 / 0-9 : 숫자
        </li>
        <li>
            . : 모든 문자열(숫자, 한글, 영어, 특수문자, 공백 포함) : 줄바꿈 x
        </li>
        <li>
            \d : 숫자  \D : 숫자가 아닌 것
            \s : 공백  \S : 공백 아닌 것
            \w : 영숫자  \W : not
            \특수기호 : \! \@ \#
        </li>
        <li>
            검색 패턴 : | or (a | b)
        </li>
        <li>
            [] : or의 묶음 / 문자들 중 하나
            /[abc]/ => "a", "b", "c" 중 하나를 포함하는
            /abc/ => "abc"를 포함하는
            [a-z] => a-z중 하나를 포함하느
            [^abc] => "a", "b", "c" 제외
        </li>
        <li>
            ^str$ => ^시작 / $끝
        </li>
    </ul>
    <script>
        let testText = 'This JavaScript Regular Expression';
        console.log(testText.match(/[is]/g));

        const fileName = ['abc.jpg', 'main.gif', 'text.txt', 'doc.pdf', 'code.js'];

        // 이미지 파일 : abc.jpg, main.gif
        // 그외 파일 구분해서 출력 : test.txt, doc.pdf, code.js
        for(let file of fileName){
            if(file.match(/(jpg|jpeg|png|gif)/i)){ //배열에 값이 있으면 true로 인식
                console.log('이미지 파일 : ' + file);
            }else{
                console.log('그외 파일 : ' + file);
            }
        }

        /* 다른 풀이과정
        let str = '';
        let imgStr = '';
        let fileStr = '';
        for(let i = 0; i < fileName.length; i++){
            str = fileName[i];
            if(str.match(/jpg|gif/g) == 'jpg' || str.match(/jpg|gif/g) == 'gif'){
                imgStr += (str + ' ');
                str = '';
            } else {
                fileStr += (str + ' ');
                str = '';
            }
        }
        console.log(`이미지 파일 : ${imgStr}`);
        console.log(`그외 파일 : ${fileStr}`);
        */
    </script>
</body>
</html>

 

▷ 출력

 

3. set & map

◈ set

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        자바 스크립트에서 사용되는 데이터 타입의 확장 개념
        array, Object, set, map
    </h1>
    <ul>
        <li>
            set 중복데이터 허용 불가 : 중복데이터가 들어오면 체크 후 하나만 남김
        </li>
        <li>
            set() : 파라미터로 주로 배열을 사용, 주로 배열로 변환하여 사용
        </li>
        <li>
            new Set() or new Set(array) : set 객체 생성
        </li>
        <li>
            set.add(value) : 데이터 추가
        </li>
        <li>
            set.delete(value) : 데이터 삭제
        </li>
        <li>
            set.has(value) : 값의 존재 여부를 true / false로 리턴
        </li>
        <li>
            set.forEach(callback function) : set 순환
        </li>
        <li>
            set.entries(), set.keys(), set.values()
            리턴타입 setIterator 형식.
        </li>
        <li>
            set.size : set size 리턴
        </li>
        <li>
            set.clear() : set 비우기
        </li>
    </ul>

    <script>
        const testSet = new Set(['html', 'css', 'js']);
        console.log(testSet);
        testSet.add('react');
        console.log(testSet);
        testSet.add('html');
        console.log(testSet);
        console.log(testSet.size);
        console.log(testSet.has('html'));
        test.delete('html');
        console.log(testSet);
        console.log(testSet.has('html'));

        testSet.forEach(function(v,i,s){
            console.log(v,i,s);
        });
        // entries() keys(), values()
        console.log(testSet.entries());
        console.log(testSet.keys());
        console.log(testSet.values());

        // 예전엔 불가능했었지만, 지금은 가능.
        testSet.keys().forEach(function(v){
            console.log(v);
        });
        
        for(let v of testSet.values()){
            console.log(v);
        }
        testSet.clear();
        console.log(testSet);
    </script>
</body>
</html>

 

◈ map

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        map key:value 형태의 데이터를 하나의 배열로 만들어서 다시 배열에 저장하는 방식
    </h1>
    <ul>
        <li>
            new Map(), new Map([key:value],[key:value],[key:value]);
        </li>
        <li>
            기본적인 중첩구조를 가지고 있음.
        </li>
        <li>
            key는 식별자로 중복 불가능
        </li>
        <li>
            get(keyName), set(keyName, value) 메서드를 제공
        </li>
        <li>
            key는 문자로 주는 것을 원칙
        </li>
        <li>
            get(keyName): key에 해당하는 value를 리턴
            set(keyName, value): key에 해당하는 value를 변경
        </li>
        <li>
            delete() / has() / forEach() / keys() / values() / entries() / size / clear 가능
        </li>
    </ul>
    <script>
        const myMap = new Map();
        myMap.set('html', 90);
        myMap.set('css', 80);
        myMap.set('js', 90);
        console.log(myMap);
        myMap.get(myMap.get('html'));

        myMap.forEach(function(v, i, s){
            console.log(v, i, s);
        })

        console.log(myMap.entries());
        console.log(myMap.keys()); // forEach 사용 가능
        console.log(myMap.values()); // forEach 사용 가능

        myMap.clear();
        console.log(myMap);
    </script>
</body>
</html>

 

▷ 출력

 

▣ 성적 등록 및 계산

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 
        input 2개 생성 => 과목, 점수 입력
        map에 추가
        출력 => map -> ul => li 형태로 출력
        결과 => 합계, 평균, 합격 여부(평균 60점이상 합격) => h3 출력
        0 ~ 100사이의 점수
    -->
        과목: <input type="text" id="subject"><br>
        점수: <input type="text" id="score"><br>
        <button type="button" id="add">추가</button>
        <button type="button" id="result">결과</button>
        <h3 id="print"></h3>
        <script>
            let print = document.getElementById('print');
            let subject = '';
            let score = 0;
            let str = ``;
            let count = 0;
            let sum = 0;
            let avg = 0;
            const myMap = new Map();
            
            document.getElementById('add').addEventListener('click', ()=>{
                subject = document.getElementById('subject').value;
                score = Number(document.getElementById('score').value);
                str = ``;
                if(score >= 0 && score <= 100){
                    myMap.set(subject, score);
                    myMap.forEach(function(v,i,s){
                        str += `<li> ${i} : ${v}</li>`;
                    });
                    count ++;
                    sum += score;
                    avg = sum / count;
                    print.innerHTML = str;
                }else{
                    alert('다시 입력해주세요');
                }
            });
            document.getElementById('result').addEventListener('click', ()=>{
                str += `<br> 합계: ${sum} / 평균: ${avg.toFixed(2)} / `;
                if(avg >= 60){
                    str += `합격 여부: pass`;
                }else{
                    str += `합격 여부: fail`;
                }
                print.innerHTML = str;
                str = ``;
            });
        </script>
</body>
</html>

 

▷ 출력

초기 상태

 

 

점수 추가 & 결과

4. 예제 문제

◎ 문제

▶ 1번

랜덤 숫자 생성 & 다시 시도

 

정답 맞추는 과정

 

정답

 

범위 제한

 

▶ 2번

 

◎ 정답

▶ 1번

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        <button id="random">랜덤 숫자 생성 버튼</button>
        <button id="new">다시 시도</button>
    </h1>
    <h3 id="printMsg"></h3>
    <h1>
        <input type="number" min="1" max="99" id="myNum">
        <button id="compareNum">정답~!!</button>
    </h1>
    <h3 id="result"></h3>
    <script>
        let printMsg = document.getElementById('printMsg');
        let result = document.getElementById('result');
        let com = 0;
        let msgStr = '';
        let count = 0;
        let resultStr = '';
        
        // 랜덤 숫자 생성 & 출력
        document.getElementById('random').addEventListener('click', ()=>{
            com = Math.floor(Math.random()*99) + 1;
            msgStr = '';
            msgStr += '컴퓨터가 랜덤수(1 ~ 99)를 생성하였습니다.';
            printMsg.innerText = msgStr;
        });
        
        // 새로 고침
        document.getElementById('new').addEventListener('click', ()=>{
            location.reload()
        });
        
        // 정답 제출
        document.getElementById('compareNum').addEventListener('click', ()=>{
            let myNum = document.getElementById('myNum').value;
            if(myNum > 1 && myNum < 100){
                count ++;
                if(myNum < com){
                    resultStr += `시도 횟수: ${count}회 / Up!!<br>`;
                }else if(myNum > com){
                    resultStr += `시도 횟수: ${count}회 / Down~~<br>`;
                }else{
                    resultStr += `시도 횟수: ${count}회 / 정답: ${com}/ 정답입니다~!<br>`;
                }
            }else{
                resultStr += `시도 횟수: ${count}회 / 1 ~ 99사이의 값만 가능합니다`;
            }
            result.innerHTML = resultStr;
        });

    </script>
</body>
</html>

 

▶ 2번

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <!-- 
        set을 이용한 로또 생성
        1등 6개, 2등 5개 + 보너스 1개, 3등 5개, 4등 4개, 5등 3개, 꽝
    -->
    <h1>1~45 로또</h1>
    <button id="ranCom">랜덤번호 6자리 생성</button>
    <h3 id="printCom"></h3> 
    <button id="ranPlayer">당첨번호 7자리 생성</button> 
    <h3 id="printPlayer"></h3> 
    <button id="result">결과 확인</button> 
    <h3 id="printResult"></h3> 
    <script>
        const printCom = document.getElementById('printCom');
        const printPlayer = document.getElementById('printPlayer');
        const printResult = document.getElementById('printResult');
        const arrayCom = [];
        const arrayPlayer = [];
        let count = 0;
        let bonus = 0;
        let last = 0;
        let str = ``;
        
        document.getElementById('ranCom').addEventListener('click', ()=>{
            str = ``;
            const setCom = new Set([]);
            while(setCom.size <= 5){
                setCom.add(Math.floor(Math.random()*45)+1);
            }
            setCom.forEach(function(v, i, s){
                str += `${v} `;
                arrayCom.push(v);
            });
            printCom.innerHTML = str;
        });
        
        document.getElementById('ranPlayer').addEventListener('click', ()=>{
            str = ``;
            const setPlayer = new Set([]);
            while(setPlayer.size <= 6){
                setPlayer.add(Math.floor(Math.random()*45)+1);
            }
            setPlayer.forEach(function(v, i, s){              //array에 요소를 push
                arrayPlayer.push(v);
            });
            last = arrayPlayer.pop();   // Player의 7번째 요소를 담음.
            arrayPlayer.forEach(function(v,i,s){                        // bonus를 제거한 array를 출력
                str += `${v} `;
            });
            str += `[${last}]`;
            printPlayer.innerHTML = str;
        });

        document.getElementById('result').addEventListener('click', ()=>{
            for(let i = 0; i <= arrayCom.length - 1; i++){
                if(arrayCom.includes(arrayPlayer[i])){
                    count ++;
                }else if(arrayCom.includes(last)){
                    bonus ++;
                }
            }
            str = '';
            if(count == 6){
                str += '1등!';
            }else if(count == 5 && bonus == 1){
                str += '2등!!';
            }else if(count == 5){
                str += '3등!!!';
            }else if(count == 4){
                str += '4등~';
            }else if(count == 3){
                str += '5등~~';
            }else{
                str += '꽝 :)'
            }
            arrayPlayer.splice(0,6);              // 당첨 번호 array 요소 제거
            printResult.innerHTML = str;
        });
    </script>
</body>
</html>

 

5. 느낀 점

로또는 항상 다시 해봐도 복잡한 것 같다. 오늘 문제들을 풀어보면서 set과 array를 다시 복습해봐야겠다.