티스토리 뷰
ES6에서 새롭게 추가된 데이터 구조 2개가 있다.
맵과 셋.
맵은 객체와 유사하고, 셋은 배열과 유사하다.
그 차이점이 뭘까?
Map
객체의 역할은 KEY와 VALUE를 연결하는 역할이다.
그런데 객체에는 몇 가지 한계들이 있다.
1. 프로토타입 체인 때문에 의도하지 않은 연결이 생길 수 있다.
2. 객체 안에 연결된 키와 값이 몇 개나 되는지 쉽게 알아낼 수 있는 방법이 없다.
3. 키는 반드시 문자열이나 심볼이어야 하므로 객체를 키로 써서 값과 연결할 수 없다..
4. 객체는 프로퍼티 순서를 보장하지 않는다.
맵은 위에서 나열한 4가지 문제점을 모두 극복해냈다.
코드를 보면서 확인해보자.
Map 인스턴스는 new연산자를 이용해서 만든다.
const u1 = {name: 'Cynthia'};
const u2 = {name: 'Jackson'};
const u3 = {name: 'Olive'};
const u4 = {name: 'James'};
const userRoles = new Map();
set()메서드를 이용해서 객체 Key에 value를 부여할 수 있다.
userRoles.set(u1, 'User');
userRoles.set(u2, 'User');
userRoles.set(u3, 'Admin');
console.log(userRoles); // Map {
// { name: 'Cynthia' } => 'User',
// { name: 'Jackson' } => 'User',
// { name: 'Olive' } => 'Admin'
// }
set() 메서드는 체인으로 연결 가능하다.
userRoles
.set(u1, 'User')
.set(u2, 'User')
.set(u3, 'Admin');
생성자에 배열의 배열을 넘기는 형태로도 가능하다. (주의: 배열의 배열임.)
const userRoles = new Map([
[u1, 'User'],
[u2, 'User'],
[u3, 'Admin']
]);
key에 해당하는 value를 알고 싶으면 get() 메서드를 사용한다.
userRoles.get(u2); // User
맵에 존재하는지 확인하는 has() 메서드도 있다.
userRoles.has(u1); // true
userRoles.has(u4); // false
userRoles.get(u4); // undefined
맵에 이미 존재하는 키에 set() 메서드를 호출하면 값이 교체가 된다.
userRoles.set(u1, 'Admin');
console.log(userRoles.get(u1)); // 'Admin'
keys() 메서드는 맵의 key를 반환, values()는 맵의 value를 반환
for (let u of userRoles.keys()) {
console.log(u);
}
// { name: 'Cynthia' }
// { name: 'Jackson' }
// { name: 'Olive' }
for (let r of userRoles.values()) {
console.log(r);
}
// User
// User
// Admin
entries() 메서드는 맵의 기본 이터레이터다.
for (let [u, r] of userRoles.entries()) {
console.log(u, r);
}
// { name: 'Cynthia' } User
// { name: 'Jackson' } User
// { name: 'Olive' } Admin
for (let [u, r] of userRoles) {
console.log(u, r);
}
// { name: 'Cynthia' } User
// { name: 'Jackson' } User
// { name: 'Olive' } Admin
이 트러블 객체보다 배열이 필요하다면 확산 연산자(spread operator)
[...userRoles.values()]; // [ 'User', 'User', 'Admin' ]
맵의 요소를 지울 때는 delete() 메서드
userRoles.delete(u2);
console.log(userRoles.has(u2)); // false
맵의 요소를 모두 지울 때는 clear() 메서드, 크기는 size 프로퍼티
userRoles.clear();
console.log(userRoles.size); // 0
정리하자면 Map은
1. 프로토타입이란 게 Map에 존재하지 않으니 고려할 필요가 없다.
2. 객체 안의 몇 개의 프로퍼티가 존재하냐 => size
3. key에 object를 사용 가능하다.
4. 프로퍼티의 순서 => 이 트러블 iterable
단순히 key와 values를 연결할 목적이라면 객체보다는 맵이 훨씬 적합해보인다.
Set
셋은 중복을 허용하지 않는 데이터 집합이다.
위 예제에서 u1이라는 사용자에게 Admin이라는 역할과 User라는 역할을 부여할 때,
매번 그 때마다 부여한다고 생각해보면,
2개의 역할을 담기 위해 배열을 생각할 수 있을 것이다.
그러면 자연스럽게 내가 넣은 역할이 이미 있는지 체크하는 로직을 넣어야 할 것이다.
만약 배열을 사용한다면
const u1 = { name: "Cynthia" };
const userRoles = new Map();
// add role to user
function addRoleToUser(user, role) {
if (userRoles.has(user)) {
const roles = userRoles.get(u1);
// check if the role already exists
if (roles.some(elem => elem === role)) return;
roles.push(role);
} else {
userRoles.set(user, [role]);
}
}
addRoleToUser(u1, "User");
addRoleToUser(u1, "Admin");
addRoleToUser(u1, "Admin");
console.log(userRoles.get(u1)); // ['User', 'Admin']
직책이 2번 들어가는 것을 방지하기 위해서
addRolteToUser라는 함수에 중간에 해당 직책이 이미 존재한는지 테스트를 해야한다.
그렇지만 Set은 이미 있는지 확인할 필요가 없다. 이미 존재하면 아무일도 일어나지 않는다.
const u1 = { name: "Cynthia" };
const roles = new Set();
roles
.add('User')
.add('Admin');
roles.add('Admin');
console.log(roles); // Set { 'User', 'Admin' }
Set을 이용해서 함수를 수정하면
const u1 = { name: "Cynthia" };
const userRoles = new Map();
function addRoleToUser(user, role) {
if (userRoles.has(user)) {
const roles = userRoles.get(u1);
roles.add(role);
} else {
const roles = new Set();
roles.add(role);
userRoles.set(user, roles);
}
}
addRoleToUser(u1, "User");
addRoleToUser(u1, "Admin");
addRoleToUser(u1, "Admin");
console.log(userRoles.get(u1)); // ['User', 'Admin']
요소를 삭제하려면 delete 전체크기는 size프로퍼티.
roles
.add('User')
.add('Admin');
roles.delete('Admin');
console.log(roles.size);
참고문헌: Learning Javascript - 이선 브라운 Chatper 10 맵과 셋
'Javascript' 카테고리의 다른 글
다형성과 다중 상속 (0) | 2020.03.01 |
---|---|
객체프로퍼티 나열 (0) | 2020.03.01 |
iterator 와 generator (0) | 2020.03.01 |
- Total
- Today
- Yesterday
- map
- 선형리스트
- 자료구조
- pm2 #cluster #Javascript
- mixin
- 집합
- virtuals
- Iterator
- static method
- 자료구조 #딕셔너리 #해시
- instance method
- alias
- mongoose
- 맵
- express-session
- Generator
- query helper
- 다중상속
- 이중 연결리스트
- index
- javascript
- resave
- set
- saveUnitialized
- Node.js
- 다형성
- MongoDB
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |