on your mark
[JAVASCRIPT.INFO] 5.7 맵과 셋 본문
5.7 맵과 셋
맵
키가 있는 데이터를 저장한다는 점에서 객체
와 유사하지만 맵
은 키에 다양한 자료형을 허용한다는 점에서 차이가 있다.
let map = new Map();
map.set('1', 'str1'); // 문자형 키
map.set(1, 'num1'); // 숫자형 키
map.set(true, 'bool1') // 불린형 키
// 객체는 키를 문자형으로 변환시키지만
// 맵은 키의 타입을 변환시키지 않고 그대로 유지한다.
alert(map.get(1)); // 'num1';
alert(map.get('1')); // 'str1';
alert(map.size); // 3
map[key]=2
로 값을 설정할 수는 있으나, map
을 일반 객체 취급하는 것이기 때문에 여러 제약이 생긴다. 따라서 map
을 사용할 때에는 set
, get
을 사용해야 한다.
맵은 키로 객체를 허용한다
let john = {name: "John"};
let visitsCountMap = new Map();
visitCountMap.set(john, 123);
map.set
을 호출할 때마다 맵 자신이 반환되기 때문에, 이를 이용하면 map.set
을 체이닝할 수 있다.
map.set('1', 'str1')
.set(1, 'num1')
.set(true, 'bool1');
맵의 요소에 반복 작업하기
다음 세 가지 메서드를 사용해 맵
의 각 요소에 반복 작업을 할 수 있다.
map.keys()
- 각 요소의 키를 모은 반복 가능한(iterable, 이터러블) 객체를 반환한다.map.values()
- 각 요소의 값을 모은 이터러블 객체를 반환한다.map.entries()
- 요소의[키, 값]
을 한 쌍으로 하는 이터러블 객체를 반환한다. 이 이터러블 객체는for .. of
반복문의 기초로 쓰인다.
let recipeMap = new Map({
['cucumber', 500],
['tomatoes', 350],
['onion', 50]
});
for(let vegetable of recipeMap.keys()){
alert(vegetable); // cucumber, tomatoes, onion
}
for(let amount of recipeMap.values()){
alert(amount); // 500, 350, 50
}
for(let entry of recipeMap) {
alert(entry); // cucumber,500 ...
}
맵은 삽입 순서를 기억하기 때문에 값이 삽입된 순서대로 순회를 실시한다. (객체가 프로퍼티 순서를 기억하지 못하는 것과 차이가 있다.)
맵은 배열과 유사하게 내장 메서드 forEach
를 지원한다.
recipeMap.forEach((value, key, map) => {
console.log(`${key}: ${value}`); // cucumber: 500 ...
})
Object.entries: 객체를 맵으로 바꾸기
각 요소가 키 값 쌍인 배열이나 이터러블 객체를 초기화 용도로 맵에 전달해 새로운 맵을 만들 수 있다.
let map = new Map([
['1', 'str1'],
[1, 'num1'],
[true, 'bool1']
]);
alert(map.get('1')); // str1
평범한 객체를 가지고 맵을 만들고 싶다면 내장 메서드 Object.entries(obj)
를 활용해야 한다. 이 메서드는 객체의 키-값 쌍을 요소([key,value]
)로 가지는 배열을 반환한다.
let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
alert(map.get('name')); // John
Object.fromEntries: 맵을 객체로 바꾸기
Object.fromEntries
를 사용하면 맵을 객체로 바꿀 수 있다. 이 메서드는 각 요소가 [key, value]
쌍인 배열을 객체로 바꿔준다.
let prices = Object.fromEntries([
['banana', 1],
['orange', 2],
['meat', 4]
]);
// prices = { banana: 1, orange: 2, meat: 4 }
alert(prices.orange); // 2
let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // 맵을 일반 객체로 변환
alert(obj.orange); // 2
map.entries()
를 호출하면 맵의 [key, value]
를 요소로 가지는 이터러블을 반환한다. (Object.fromEntries
를 사용하기 위한 형태)
셋
셋(Set)
은 중복을 허용하지 않는 값을 모아놓은 특별한 컬렉션이다. 셋에 키가 없는 값이 저장된다.
셋 내에 동일한 값이 있다면 set.add(value)
를 아무리 많이 호출하더라도 반응이 없다.
let set = new Set();
let john = {name: "John"};
let pete = {name: "Pete"};
let mary = {name: "Mary"};
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);
alert(set.size); // 3
for(let user of set){
console.log(user.name); // John, Pete, Mary
}
셋의 값에 반복 작업하기
for .. of
나 forEach
를 사용하면 셋의 값을 대상으로 반복 작업을 수행할 수 있다.
let set = new Set(["oranges", "apples", "bananas"]);
for(let value of set) alert(value);
set.forEach((value, valueAgain, set) => {
alert(value);
})
forEach
에 쓰인 콜백함수는 세 개의 인수를 받는데, 첫 번째는 value
, 두 번째도 같은 값인 valueAgain
을 받는다. 동일한 값이 인수에 두 번 등장한다. 이렇게 구현된 이유는 Map
과의 호환성 때문이다. Map
의 forEach
에 쓰인 콜백이 세 개의 인수를 받을 때를 위해 위와 같이 구현되어 있다.
'WEB > Javascript' 카테고리의 다른 글
[JAVASCRIPT.INFO] 5.9 Object.keys, values, entries (0) | 2023.01.11 |
---|---|
[JAVASCRIPT.INFO] 5.8 위크맵과 위크셋 (0) | 2023.01.10 |
[JAVASCRIPT.INFO] 5.6 iterable 객체 (0) | 2023.01.09 |
[JAVASCRIPT.INFO] 셔플 알고리즘(shuffle) (0) | 2023.01.09 |
[JAVASCRIPT.INFO] 5.5 배열과 메서드 (1) | 2023.01.09 |