Map & Set
Map
- Map 객체는 키-값 쌍을 가지는 객체 자료형의 한 종류
let m = new Map();
// Map에 값을 넣기
// set메서드는 m에 값을 넣은 결과를 반환
m.set('하나', 1);
m.set(1, '하나');
m.set(true, 1);
m.set(false, 0);
// Map의 값에 접근하기
console.log(m.get('하나')); // 1
console.log(m.get(true)); // 1
// Map의 값이 있는지 확인하기
console.log(m.has('하나')); // true -> 값이 있음 = true
// Map의 값을 제거하기
console.log(m.delete('하나')); // true -> 키를 제거하면 true 반환
console.log(m.has('하나')); // false -> 키가 존재하지 않으므로 false 반환
console.log(m); //현재 /Map 상태 출력
/*
1 => 하나
true => 1
false => 0
*/
// Map의 크기를 확인하기
console.log(m.size); // 3 -> 3개의 키-값 쌍이 존재
// Map의 모든 값을 지우기
m.clear()
Map의 여러가지 활용법
- Map의 순회
for (const variable of m) {
console.log(`m을 순회 key: ${variable[0]}`);
console.log(`m을 순회 value: ${variable[1]}`);
}
- Map의 값에 접근
console.log(m.keys()); // 키 가져오기
console.log(m.values()); // 값 가져오기
console.log(m.entries()); // 키-값 쌍 가져오기
- 인덱스를 가지는 자료형을 맵핑하기
let temp = new Map([[1, 10],
[2, 20],
[3, 30],
[4, 40]]);
console.log(temp);
/*
{1=>10, 2=>20, 3=>30, 4=>40}
*/
Map과 Object의 차이
- Object의 키는 문자열 타입으로만 지정해야함 / Map의 키는 모든 값을 가질 수 있음
- Object는 크기를 사용자가 직접 수동으로 알아내야 함 / Map은 size를 통해 크기를 쉽게 얻을 수 있음
- Map은 데이터를 추가하거나 제거하는 작업에서 Object보다 더 나은 성능을 보임
objMap = new Map();
objMap.set('one', 1);
objMap.set('two', 2);
objMap.set('three', 3);
console.log(objMap.size); // 3
obj = {hi: 1, hi2: 2, hi3: 3, hi4: 4};
console.log(obj.length); // undefined
console.log(obj.size); // undefined
const m = new Map();
// set을 이용하여 map에 값 추가
m.set("하나", 1);
m.set(1, "하나");
m.set(true, 1);
m.set(false, 0);
const obj = {name: "kim", age: 20};
const key = "nickName";
// object에서 키값 추가
obj.nickName = "뽀로로";
obj[key] = "뽀로로";
// map의 값에 접근
console.log(m.get("하나")); // 1
console.log(m.get(true)); // 1
// Map 객체에서 값이 있는지 확인하기
m.has("하나");
m.has("둘");
// Object에서 값이 있는지 확인하기
const obj = {
name: "뽀로로",
age: 20,
};
// map 객체에서 값 지우기
m.delete("하나");
// Object에서 값 지우기
delete obj.name;
// map 길이 가져오기
m.size;
// Object 길이 가져오기
Object.keys(obj).length;
Set
- 모든 타입의 값을 저장하는 객체자료형의 한 종류
- 객체 안의 값은 중복을 허용하지 않음
let s = new Set('abcdeeeeeeeee');
console.log(s); // Set(5) ['a', 'b', 'c', 'd', 'e']
console.log(s.size); // 5
- Set에 값을 추가하기
s.add('f');
console.log(s); // Set(6) ['a', 'b', 'c', 'd', 'e', 'f']
- Set을 순환하기
for (var variable of s) {
console.log(variable);
}
/*
a
b
c
d
e
f
*/
- 값이 배열인 경우
let ss = new Set('abcdeeeeeeeee'.split(''));
console.log(ss); // Set(6) {'a', 'b', 'c', 'd', 'e'}
- Set의 값을 제거하기
ss.delete('b');
console.log(ss); // Set(4) {'a', 'c', 'd', 'e'}
- Set의 값을 확인하기
console.log(ss.has('a')); // true
- Set의 모든 값을 제거하기
ss.clear();
console.log(ss); //Set(0)
- 집합
let a = new Set('abc');
let b = new Set('cde');
// 교집합
let cro = [...a].filter(value => b.has(value));
// 합집합
let union = new Set([...a].concat(...b));
// 차집합
let dif = [...a].filter(x => !b.has(x));
연습문제
회사 게시판에는 총 6개의 게시물이 있고, 각각의 게시물에 게시자 데이터를 뽑은 것이 '회사게시판 변수이다.'
let 회사게시판 = ["뽀로로", "뽀로로", "뽀로로", "루피", "루피", "에디"];
문제1) 몇 명이 게시판에 게시물을 썼는지? (이름이 같은 경우는 동일인물)
let company = new Set(회사게시판);
company.size;
console.log(company.size); // 3 -> 뽀로로, 루피, 에디
문제2) 각각 몇 개의 게시물을 작성했는가?
for (const i of name) {
console.log(name, 회사게시판.filter(writer => writer === name)
};
for (const name of company) {
console.log(name, 회사게시판.filter(writer => writer === name).length)
};
/*
뽀로로 3
루피 2
에디 1
*/
let corp = new Map();
for (const name of 회사게시판) {
// 순회돌면서 해당 key값을 업데이트해주는 식으로
corp.set(name, (corp.get(name) || 0) + 1);
// (map.get(name) || 0)
// 해석 -> map.get(name)에 값이 있으면 map.get(name)을 남기고 아니면 0을 남김
}
// 위 코드 설명
corp.set("뽀로로", (corp.get("뽀로로") || 0) + 1); // map.set("뽀로로", 1)
corp.set("뽀로로", (corp.get("뽀로로") || 0) + 1); // map.set("뽀로로", 2)
corp.set("뽀로로", (corp.get("뽀로로") || 0) + 1); // map.set("뽀로로", 3)
corp.set("루피", (corp.get("루피") || 0) + 1); // map.set("루피", 1)
JSON
JSON이란
- JSON = JavaScript Object Notation
- 자바스크립트에서 객체를 표현하는 형식으로 데이터를 표현한 것
- 다른 방식에 비해 가볍고 자바스크립트와 호환성이 높아 널리 사용
- 텍스트로 표현된 정보의 덩어리
JSON 기본형태
{
"squadName": "슈퍼히어로",
"members": [
{
"name": "아이언맨",
"age": 29,
"본명": "토니 스타크"
},
{
"name": "헐크",
"age": 39,
"본명": "부르스 배너"
}
]
}
JSON 기본 자료형
- Number
- String
◽ 0개 이상의 유니코드 문자를 지원
◽ 문자열은 따옴표를 이용
◽ 역슬래시 이스케이프 문법을 지원
- Boolean
◽ true / false
- Array 0 이상의 길이를 가진 리스트
◽ 대괄호로 나타냄
◽ 요소는 쉼표로 구분
- Object
◽ JS에서 사용하는 Object현태로 사용
◽ 사용되는 자료형은 JSON의 자료형과 동일
- null
◽ 빈 값은 null로 나타냄
JSON 메서드
JSON.parse( )
- JSON 문자열을 자바스크립트 객체로 변환
JSON.stringify( )
- 자바스크립트 객체를 JSON 문자열로 변환
// JSON을 이용한 깊은 복사
let l = [10, 20, 30];
let a = JSON.parse(JSON.stringify(1));
a[0] = 1000;
console.log(l); // (3) [10, 20, 30]
- JSON을 이용한 깊은 복사
◽ 객체를 문자열화했다가 다시 객체로 변환하기 때문에 새로운 객체를 생성하는 것과 동일
◽ 함수는 제대로 복사가 불가능함
◽ 제대로된 깊은 복사를 위해서는 structuredClone 메소드를 사용해야 함
JSON 응용1
const 호텔 = [
{
이름: "하나호텔",
위치: "제주도 제주시 111",
가격: { A: 50000, B: 30000, C: 15000 },
방개수: 50,
예약자수: 25,
남은방의개수: function () {
return this.방개수 - this.예약자수;
},
},
{
이름: "둘호텔",
위치: "제주도 제주시 222",
가격: { A: 100000, B: 80000, C: 30000 },
방개수: 100,
예약자수: 30,
남은방의개수: function () {
return this.방개수 - this.예약자수;
},
},
{
이름: "셋호텔",
위치: "제주도 제주시 333",
가격: { A: 80000, B: 60000, C: 40000 },
방개수: 120,
예약자수: 80,
남은방의개수: function () {
return this.방개수 - this.예약자수;
},
},
];
console.log(호텔.filter((호텔) => 호텔.이름 == "셋호텔"));
console.log(
호텔.map((호텔) => ({
이름: 호텔.이름,
위치: 호텔.위치,
가격: 호텔.가격,
방개수: 호텔.방개수,
예약자수: 호텔.예약자수,
// 물론 이름을 붙이는 간단한 연산뿐만 아니라, 나라별 시간 표기법을 별도로 표시해준다던지 좀 더 복잡한 연산도 가능
남은방의개수: 호텔.방의개수 - 호텔.예약자수,
}))
);
let a = [5, 4, 3, 2, 1];
console.log(a.sort((a, b) => a - b));
console.log(호텔.sort((a, b) => a.방개수 - b.방개수));
JSON 응용2
<button onclick="renderTable(jsonData)">데이터 호출!</button>
<table id="renderingDataTable">
<thead>
<tr>
<th onclick="sort('_id')">_id</th>
<th onclick="sort('age')">age</th>
<th onclick="sort('eyeColor')">eyeColor</th>
<th onclick="sort('name')">name</th>
<th onclick="sort('gender')">gender</th>
<th onclick="sort('email')">email</th>
<th onclick="sort('phone')">phone</th>
</tr>
</thead>
<tbody></tbody>
</table>
const jsonData = [
{
"_id": "5e80777f673acf89c007ff91",
"age": 27,
"eyeColor": "green",
"name": "Angelina Chang",
"gender": "female",
"email": "angelinachang@kangle.com",
"phone": "+1 (938) 477-2821"
},
{
"_id": "5e80777feee717674b817fd2",
"age": 25,
"eyeColor": "green",
"name": "Deidre Cobb",
"gender": "female",
"email": "deidrecobb@kangle.com",
"phone": "+1 (938) 477-2824"
},
{
"_id": "5e80777fac368a4578dda85d",
"age": 25,
"eyeColor": "blue",
"name": "Jolene Franks",
"gender": "female",
"email": "jolenefranks@kangle.com",
"phone": "+1 (985) 536-3981"
},
{
"_id": "5e80777ff3717874cbc78e44",
"age": 31,
"eyeColor": "brown",
"name": "Waters Hardin",
"gender": "male",
"email": "watershardin@kangle.com",
"phone": "+1 (938) 559-2224"
},
{
"_id": "5e80777fe36842ea9e024fcd",
"age": 34,
"eyeColor": "green",
"name": "Jody Chaney",
"gender": "female",
"email": "jodychaney@kangle.com",
"phone": "+1 (878) 587-2602"
},
{
"_id": "5e80777fafd591f57344eb33",
"age": 31,
"eyeColor": "green",
"name": "Ortiz Maldonado",
"gender": "male",
"email": "ortizmaldonado@kangle.com",
"phone": "+1 (986) 509-2753"
},
{
"_id": "5e80777f20e48e9ada226862",
"age": 25,
"eyeColor": "brown",
"name": "Stacy Burris",
"gender": "female",
"email": "stacyburris@kangle.com",
"phone": "+1 (864) 577-3500"
},
{
"_id": "5e80777faf334f84a2c90595",
"age": 33,
"eyeColor": "brown",
"name": "Davenport Levy",
"gender": "male",
"email": "davenportlevy@kangle.com",
"phone": "+1 (990) 600-2700"
},
{
"_id": "5e80777fe9d516f0da793b7e",
"age": 32,
"eyeColor": "brown",
"name": "Lenora Rivas",
"gender": "female",
"email": "lenorarivas@kangle.com",
"phone": "+1 (835) 549-3209"
},
{
"_id": "5e80777fba91e9aeeb5ce989",
"age": 35,
"eyeColor": "brown",
"name": "John Fischer",
"gender": "female",
"email": "johnfischer@kangle.com",
"phone": "+1 (969) 493-3495"
},
{
"_id": "5e80777f63b89c8cb73127b8",
"age": 23,
"eyeColor": "brown",
"name": "Aurora Robles",
"gender": "female",
"email": "aurorarobles@kangle.com",
"phone": "+1 (900) 579-2424"
},
{
"_id": "5e80777faac1a3f50eacfbd1",
"age": 20,
"eyeColor": "brown",
"name": "Solis Hays",
"gender": "male",
"email": "solishays@kangle.com",
"phone": "+1 (930) 450-2123"
},
{
"_id": "5e80777ffd19fbf487e3957c",
"age": 26,
"eyeColor": "blue",
"name": "Graves Jackson",
"gender": "male",
"email": "gravesjackson@kangle.com",
"phone": "+1 (810) 556-3478"
},
{
"_id": "5e80777ff3bd76dd30824028",
"age": 22,
"eyeColor": "brown",
"name": "Sharron Joyner",
"gender": "female",
"email": "sharronjoyner@kangle.com",
"phone": "+1 (991) 418-2210"
},
{
"_id": "5e80777fd0f579261a830c2f",
"age": 37,
"eyeColor": "brown",
"name": "Patty Bernard",
"gender": "female",
"email": "pattybernard@kangle.com",
"phone": "+1 (940) 558-3881"
},
{
"_id": "5e80777fba4fc442f7353d84",
"age": 23,
"eyeColor": "brown",
"name": "Sandra Foreman",
"gender": "female",
"email": "sandraforeman@kangle.com",
"phone": "+1 (864) 500-3123"
},
{
"_id": "5e80777fa0897694765e4040",
"age": 35,
"eyeColor": "blue",
"name": "Hyde Melendez",
"gender": "male",
"email": "hydemelendez@kangle.com",
"phone": "+1 (964) 487-2694"
},
{
"_id": "5e80777fcf1f69b3350b06c1",
"age": 40,
"eyeColor": "green",
"name": "Evans Wagner",
"gender": "male",
"email": "evanswagner@kangle.com",
"phone": "+1 (944) 448-3591"
},
{
"_id": "5e80777fd311822be4597959",
"age": 40,
"eyeColor": "brown",
"name": "Robinson Lynn",
"gender": "male",
"email": "robinsonlynn@kangle.com",
"phone": "+1 (983) 564-3761"
},
{
"_id": "5e80777f481e9934e9fabdce",
"age": 27,
"eyeColor": "brown",
"name": "Best Ewing",
"gender": "male",
"email": "bestewing@kangle.com",
"phone": "+1 (950) 477-3573"
},
{
"_id": "5e80777fbf35be0eb2c2360a",
"age": 22,
"eyeColor": "green",
"name": "Bird Long",
"gender": "male",
"email": "birdlong@kangle.com",
"phone": "+1 (843) 497-2151"
},
{
"_id": "5e80777f37564dd622dfac58",
"age": 35,
"eyeColor": "green",
"name": "Flynn Albert",
"gender": "male",
"email": "flynnalbert@kangle.com",
"phone": "+1 (835) 422-2151"
},
{
"_id": "5e80777fa4080ca9c9a2a8f7",
"age": 39,
"eyeColor": "brown",
"name": "Avila Chen",
"gender": "male",
"email": "avilachen@kangle.com",
"phone": "+1 (985) 515-2235"
},
{
"_id": "5e80777fbf2492c1f4f6c7d2",
"age": 38,
"eyeColor": "green",
"name": "Colette Sweet",
"gender": "female",
"email": "colettesweet@kangle.com",
"phone": "+1 (971) 578-3870"
},
{
"_id": "5e80777f9dc7e14e19c042a7",
"age": 39,
"eyeColor": "brown",
"name": "Deirdre Reilly",
"gender": "female",
"email": "deirdrereilly@kangle.com",
"phone": "+1 (832) 546-2673"
},
{
"_id": "5e80777f28590be173115fdf",
"age": 38,
"eyeColor": "blue",
"name": "Carpenter Kaufman",
"gender": "male",
"email": "carpenterkaufman@kangle.com",
"phone": "+1 (963) 452-3989"
},
{
"_id": "5e80777fa4062298ee3772aa",
"age": 30,
"eyeColor": "green",
"name": "Angela Cote",
"gender": "female",
"email": "angelacote@kangle.com",
"phone": "+1 (868) 471-3444"
},
{
"_id": "5e80777fe70152016f07e965",
"age": 24,
"eyeColor": "blue",
"name": "Carter Mueller",
"gender": "male",
"email": "cartermueller@kangle.com",
"phone": "+1 (943) 492-2942"
},
{
"_id": "5e80777f162e512bf3be2b7e",
"age": 35,
"eyeColor": "blue",
"name": "Nola Hancock",
"gender": "female",
"email": "nolahancock@kangle.com",
"phone": "+1 (851) 523-2333"
},
{
"_id": "5e80777f178b7460aeb79784",
"age": 35,
"eyeColor": "green",
"name": "Mcconnell Mosley",
"gender": "male",
"email": "mcconnellmosley@kangle.com",
"phone": "+1 (807) 460-2627"
}
];
let click = true;
function sort(key){
if (click) {
click = false;
let sortedData = jsonData.sort((a, b) => (a[key] < b[key] ? -1 : (a[key] > b[key] ? 1 : 0)));
renderTable(sortedData);
} else {
click = true;
let sortedData = jsonData.sort((a, b) => (a[key] > b[key] ? -1 : (a[key] < b[key] ? 1 : 0)));
renderTable(sortedData);
}
}
function renderTable(data){
let tableBodyData = [];
console.log('?')
for (var variable of data) {
tableBodyData.push(`
<tr>
<td>${variable._id}</td>
<td>${variable.age}</td>
<td>${variable.eyeColor}</td>
<td>${variable.name}</td>
<td>${variable.gender}</td>
<td>${variable.email}</td>
<td>${variable.phone}</td>
</tr>
`)
}
document.querySelector('#renderingDataTable > tbody').innerHTML = tableBodyData.join('');
}
JSON 응용3
<button onclick="renderTable(호텔)" type="button" name="button">클릭해!!</button>
<table id="rederingDataTable">
<thead>
<tr>
<th onclick="sort('이름')">이름</th>
<th onclick="sort('위치')">위치</th>
<th onclick="sort('가격')">가격</th>
<th onclick="sort('방의개수')">방의개수</th>
<th onclick="sort('예약자수')">예약자수</th>
</tr>
</thead>
<tbody></tbody>
</table>
const 호텔 = [{
'이름' : '하나호텔',
'위치' : '제주도 제주시 001',
'가격' : {'A':50000, 'B':30000, 'C':15000},
'방의개수' : 50,
'예약자수' : 25,
'남은방의개수' : function(){return this.방의개수 - this.예약자수}
},{
'이름' : '둘호텔',
'위치' : '제주도 제주시 002',
'가격' : {'A':100000, 'B':60000, 'C':30000},
'방의개수' : 100,
'예약자수' : 30,
'남은방의개수' : function(){return this.방의개수 - this.예약자수}
},{
'이름' : '셋호텔',
'위치' : '제주도 제주시 003',
'가격' : {'A':80000, 'B':50000, 'C':30000},
'방의개수' : 120,
'예약자수' : 80,
'남은방의개수' : function(){return this.방의개수 - this.예약자수}
}];
function sort(name){
let 정렬된호텔 = 호텔.sort((a, b) => (b[name] - a[name]));
renderTable(정렬된호텔);
}
function renderTable(호텔기본값){
let tableBody = [];
// JSON.stringify({ x: 5, y: 6 })
for (var variable of 호텔기본값) {
tableBody.push(`
<tr>
<td>${variable.이름}</td>
<td>${variable.위치}</td>
<td>${JSON.stringify(variable.가격)}</td>
<td>${variable.방의개수}</td>
<td>${variable.예약자수}</td>
</tr>
`);
}
document.querySelector('#rederingDataTable > tbody').innerHTML = tableBody.join('');
}
'ESTsoft > 프론트엔드 오르미 1기' 카테고리의 다른 글
[EST] 240718 JavaScript-10 (0) | 2024.07.31 |
---|---|
[EST] 240717 JavaScript-09 (0) | 2024.07.31 |
[EST] 240715 JavaScript-07 (0) | 2024.07.25 |
[EST] 240712 JavaScript-06 (1) | 2024.07.25 |
[EST] 240711 JavaScript-05 (0) | 2024.07.23 |