맵과 셋
- 객체 : 키가 있는 컬렉션을 저장
- 배열 : 순서가 있는 컬렉션을 저장
맵(Map)
: 키가 있는 데이터를 저장하지만 키에 대한 다양한 자료형을 허용한다
Map’s main methods and properties
- new Map() : 맵을 만든다
- map.set(key, value) : key를 이용해 value를 저장한다
- map.get(key) : key에 해당하는 값을 반환, 없다면 key가 없다면 undefined 반환한다
- map.has(key) : key가 존재하면 true, 존재하지 않으면 false 반환한다
- map.delete(key) : key에 해당하는 값을 삭제
- map.clear() : 맵 안의 모든 요소를 제거한다
- map.size : 요소의 개수를 반환한다
let map = new Map()
map.set(‘1’, ‘str1’); // string key
map.set(1, ‘num1’); // number key
map.set(true, ‘bool1’); // boolean key
// 맵은 객체와 다르게 키의 타입을 변환시키지 않는다, 반면 객체는 key ➡️ string
console.log(map.get(1)); // num1
console.log(map.get(‘1’)); // str1
console.log(map.size); // 3
// 객체형 key를 사용한 map 만들기
let john = { name: “John” };
let visitsCountMap = new Map();
visitsCountMap.set(john, 123);
console.log(visitsCountMap.get(john)); // 123
// 객체에서 객체형 key 사용해보기
let john = { name: "John" };
let visitsCountObj = {};
visitsCountObj[john] = 123; // 객체(john)를 키로 해서 객체에 값(123)을 저장
// 키가 들어갈 자리에 `object Object`를 써줘야 원하는 값(123)이 나온다
alert( visitsCountObj["[object Object]"] ); // 123
맵(map)의 특징)
- 맵을 사용할 땐 맵 전용 메서드와 프로퍼티를 사용해야 한다
- 맵은 key로 객체를 허용한다
- 맵이 사용하는 알고리즘으로 인해 NaN도 key로 사용할 수 있다
- 맵의 체이닝 : map.set을 호출할 때마다 자신이 반환되어 체이닝을 할 수 있다
map.set(‘1’, ‘str1’)
.set(1, ‘num1’)
.set(true, ‘bool1’);
맵의 요소에 반복 작업하기
- map.keys() : 각 요소의 key를 모은 iterable 객체를 반환
- map.values() : 각 요소의 value을 모은 iterable 객체 반환
- map.entries() : 요소의 [key, value] : property iterable 객체 반환, 이 iterable 객체가 for..of 반복문의 기초로 쓰인다
let recipeMap = new Map([
[‘cucumber’, 500],
[‘tomatoes’, 350],
[‘onion’, 50]
]);
for (let vegetable of recipeMap.keys()) {
console.log(vegetable);
}
for (let amount of recipeMap.values()) {
console.log(amount);
}
for (let entry of recipeMap) { // map.entries() 와 동일
console.log(entry);
}
맵은 삽입 순서를 기억하기 때문에 순서대로 순회한다(객체는 순서를 기억 못함)
추가로 맵은 배열과 유사하게 내장 메서드 forEach를 지원한다
recipeMap.forEach((value, key, map) =. {
console.log(`${key}: ${value}`);
});
Object.entries: 객체를 맵으로 바꾸기
- [key, value] : property의 요소를 가진 배열이나 iterable 객체를 초기화 용도로 맵에 전달해 새로운 맵을 만들 수 있다
// 배열
let map = new Map([
[‘1’, ‘str1’],
[1, ‘num1’],
[true, ‘bool1’]
]);
console.log(map.get(‘1’)); // str1
// 객체
let obj = {
name: “kim”,
age: 26
};
let map = new Map(Object.entries(obj));
console.log(map.get(‘name’)); // kim
// 객체 ➡️ 배열 ➡️ 맵
Object.fromEntries: 맵을 객체로 바꾸기(Object.entries의 반대)
let prices = Object.fromEntries([
[’banana’, 1],
[’orange, 2],
[’meat’, 4]
});
consoe.log(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()); // entries()를 생략하면 코드가 더 짧아진다
console.log(obj.orange); // 2
// 맵 ➡️ 객체
셋(Set)
: 중복을 허용하지 않는 값을 모아놓은 특별한 컬렉션, key가 없는 값이 저장된다
Set of main method
- new Set(iterable) : set을 만든다, iterable 객체를 전달받으면(대게 배열을 전달받음) 그 안의 값을 복사해 셋을 넣어준다
- set.add(value) : 값을 추가하고 셋 자신을 반환한다
- set.delete(value) : 값을 제거하고 호출 시점에 셋 내에 값이 있어서 제거에 성공하면 true 아니면 false를 반환한다
- set.has(value) : 셋 내에 값이 존재하면 true, 존재하지 않으면 false 반환하다
- set.clear() : 셋을 비운다
- set.size : 셋에 몇 개의 값이 있는지 세준다
셋 내에 동일한 값이 있다면 set.add(value)를 아무리 많이 호출해도 반응이 없다
// 방문자 중복 기록 방지
let = new Set()
let john = { name: “John” };
let pete = { name: “Pete” };
let mary = { name: “Mary” };
set.add(john);
set.add(pete);
set.add(john);
set.add(mary);
set.add(john);
console.log(set.size); // 3, set에는 유일무이한 갑만 저장된다
for (let user of set) {
console.log(user.name);
}
셋의 값에 반복 작업하기
for..of 나 forEach를 사용하면 셋의 값을 대상으로 반복 작업을 할 수 있다
let set = new Set([“oranges”, “apples”, “bananas”]);
for (let value of set) console.log(value);
set.forEach((value, valueAgain, set) = > {
console.log(value);
});
왜 동일한 값을 받는 인수가 두개일까?
: 맵과의 호환성 때문이다, 맵의 forEach에 쓰인 콜백이 세 개의 인수를 받을 때를 위해서(미래를 대비해서~) 그래서 맵 ➡️ 셋, 셋 ➡️ 맵이 가능하다
셋의 반복 작업을 위한 메서드
- set.keys() : 셋 내의 모든 값을 포함하는 iterable 객체를 반환한다
- set.values() : set.keys()와 동일한 작업을 한다, 맵과의 호환성을 위해 만들어진 메서드
- set.entries() : 셋 내의 각 값을 이용해 만든 [value, value] 배열을 포함하는 iterable 객체를 반환한다 이것또한 맵과의 호환성을 위해 만들어졌다