맵(Map)
데이터와 키를 같이 저장할 수 있는 자료 구조
맵은 키가 있는 데이터를 저장한다는 점에서 객체(obj)와 유사
▶ 맵의 특징
- Key-value의 한 쌍으로 이루어진 데이터 집합
- 본래 key 삽입 순서를 기억
- 어떤 value(객체와 원시값*)든 key 혹은 value로 사용될 수 있음(key의 타임에 제약이 없음)
- 삽입 순서로 요소를 반복(루프는 각 반복에 대해 for...of 루프의 [key, value] 배열을 반환)
- Key 중복 허용 불가(동일한 키로 값을 추가하면 기존 값을 덮어씀)
- Value에는 중복이 허용
- NaN 도 key로 쓸 수 있음
- Key equality는 sameValueZero 알고리즘을 기반으로 함
- 뛰어난 검색 속도를 가지고 있다는 장점이 있음
- 인덱스가 따로 존재하지 않아서 iterator를 사용
▶ 맵과 객체(Object)의 차이점
- 키의 타입: 객체는 키로 문자열과 심볼(Symbol)만 사용할 수 있는 반면 맵은 키로 모든 데이터 타입이 가능
- 요소 순서: 객체는 요소들의 순서가 보장되지 않음. 요소들의 추가된 순서와 상관없이 저장되며, 반복 시 순서가 일정하지 않을 수 있음 반면, 맵은 요소들의 순서가 보존되기 때문에 요소들을 추가한 순서대로 순회할 수 있음
- 크기 확인: 객체는 요소의 개수를 쉽게 확인할 수 있는 메서드나 속성을 제공하지 않는 반면 맵은 size 프로퍼티를 크기(요소의 개수)를 확인할 수 있음
- 상속: 객체는 프로토타입 체인을 통해 상속 관계를 형성할수 있는 반면 맵은 키-값 쌍의 저장을 목적으로 하는 독립된 자료구조로 상속을 사용하지 않음
- 이터레이션: 객체는 for...in 문법을 통해 요소들을 이터레이션할 수 있고 맵은 for...of 문법 또는 forEach 메서드를 통해 요소들을 이터레이션할 수 있음
▶ 맵의 주요 메서드와 프로퍼티
new Map() // 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 안의 모든 요소 제거
map.size // 요소의 개수 반환
map.keys() // 각 요소의 키를 모아둔 iterable 객체를 반환
map.values() // 각 요소의 값을 모은 iterable 객체를 반환
map.entries() // 요소의 [key, value] 한 쌍으로 하는 iterable 객체 반환(이 객체는 for...of 루프의 기초로 쓰임)
▶ 맵의 요소 반복
세 가지 메서드(key, value, entries)를 통해 맵의 각 요소를 뽑아 반복 작업을 하거나, 배열처럼 내장 메서드인 forEach를 사용
let animals = new Map();
animals.set("dog", "woof")
.set("cat", "meow")
.set("elephant", "toot");
for (let name of animals.keys()) {
console.log(name); // dog, cat, elephant
}
for (let howling of animals.values()) {
console.log(howling); //woof, meow, toot
}
for (let [key, value] of animals) { // animals는 animals.entries()와 동일
console.log(`${key} goes ${value}`);
// dog goes woof , cat goes meow, elephant goes toot
}
animals.forEach((value, key, map) => { //forEach(callFuc(value, key, map))
console.log(`${key} : ${value}`); // dog : woof, cat : meow, elephant : toot
});
▶ 객체를 맵으로, 맵을 객체로 변환
맵은 키가있는 데이터를 저장한다는 점에서 객체와 유사하함
그래서 그런지 서로 변환이 가능
객체를 맵으로 변환
let obj = {
dog : "woof",
cat : "meow",
elephant : "toot"
}
let animals = new Map(Object.entries(obj));
console.log(animals);
// Map(3) {'dog' => 'woof', 'cat' => 'meow', 'elephant' => 'toot'}
맵을 객체로 변환
let animals = new Map();
animals.set("dog", "woof")
.set("cat", "meow")
.set("elephant", "toot");
let obj = Object.fromEntries(animals);
console.log(obj); //{dog: 'woof', cat: 'meow', elephant: 'toot'}
맵에서 객체로 변환할때는 모든 key값이 문자열로 바뀌니 주의
셋(Set)
중복이 존재할 수 없는 자료구조
어떤 값이라도 그 Set 콜렉션 내에서 유일함
셋은 키가 없는 값을 저장한다는 점에서 배열(array)과 유사
▶ 특징
- 모든 값들은 고유해서 새로운 값을 추가하거나 변경하면 값 비교가 이루어짐
- 인덱스를 사용하지 않음
- 인덱스 매개변수가 없음
- 집합에 빗대어 생각할 수 있음
- 원시값과 객체 참조 모두 유일한 값을 저장할 수 있음(즉, 동일한 값을 중복하여 포함할 수 없음)
- 삽입 순서대로 요소를 순회
- NaN 과 undefined 도 Set에 저장할 수 있음
- 조회에 있어서 Array에 비해 훨씬 빠름(해시테이블 자료구조때문, 검색속도가 빠르고 삽입 삭제 유리 - O(1))
- 인덱스가 따로 존재하지 않기 때문에 iterator를 사용(value에 반복 작업 하기 위해서 for...of 나 forEach 를 사용)
▶ 셋과 배열(array)의 차이점
- 중복 요소의 처리: 배열은 중복된 요소를 포함할 수 있으나 셋은 유일한 요소만 포함될 수 있어 중복된 요소가 자동으로 제거됨
- 반복 가능성: 배열은 for루프나 forEach 같은 배열 순회 메서드를 사용하여 요소를 반복할 수 있으며 셋은 반복 가능한 객체이므로 for...of 루프는 forEach 메서드를 사용하여 요소를 반복할 수 있음
- 인덱스: 배열은 인덱스를 통해 요소에 접근할 수 있으나 셋은 인덱스를 사용하지 않음
- 성능: 요소 탐색, 추가, 삭제의 경우 셋이 배열에 비해 높은 성능을 보여줌
▶ 주요 메서드
new Set(iterable) // set 생성. iterable 객체를 전달받으면(대게 배열) 그 안의 값을 복사해서 set에 넣어줌
set.add(value) // value를 추가하고 set 자신을 반환
set.delete(value) // value 제거. 호출 시점에 set 내에 value가 있어서 제거에 성공하면 true, 아니라면 false를 반환
set.has(value) // set 내에 값이 존재하면 true, 아니면 false
set.clear() // set안의 모든 요소 제거
set.size // 요소의 개수 반환
set.keys() // set 내의 모든 값을 포함하는 iterable 객체 반환
set.values() // set.keys와 동일한 작업을 함 map과의 호환성을 위해 만들어진 메서드
set.entries() // set 내의 각 값을 이용해서 만든 [value, value] 배열을 포함하는 iterable 객체 반환. map과의 호환성을 위해 만들어졌음
▶ 셋의 요소 반복
세 가지 메서드 (key, value, entries) 를 통해 맵의 각 요소를 뽑아 반복 작업을 하거나, 배열처럼 내장 메서드인 forEach를 사용
let mineSet = new Set([0, 1, 2, 3]);
for (let key of mineSet.keys()) {
console.log(key); // 0, 1, 2, 3
}
for (let value of mineSet.values()) {
console.log(value); // 0, 1, 2, 3
}
for (let data of mineSet) {// mineSet mineSet.entries()와 동일
console.log(data); // 0, 1, 2, 3
}
mineSet.forEach((value, valueAgain, set) => {
console.log(`${value} : ${valueAgain}`);
// 0 : 0, 1 : 1, 2 : 2, 3 : 3
});
▶배열을 셋으로, 셋을 배열로 변환
배열을 셋으로 변환
const array = [0, 1, 2, 3];
let mineSet = new Set(array);
console.log(mineSet); // Set(4) {0, 1, 2, 3}
셋을 배열로 변환
let mineSet = new Set([0, 1, 2, 3]);
// 1. 전개 연산자 사용
const arr1 = [...mineSet];
console.log(arr1); // [0, 1, 2, 3]
// 2. Array.from 사용
const arr2 = Array.from(mineSet);
console.log(arr2); // [0, 1, 2, 3]
Reference
'JS' 카테고리의 다른 글
Proxy(Object.defineProperty와 비교) (0) | 2024.06.12 |
---|---|
Class(extends, super) (0) | 2024.06.12 |
구조 분해(Destructuring), 나머지/전개 연산자(Rest/Spread Operator) (0) | 2024.06.12 |
ES-Module(ESM, ECMAScript Modules) (0) | 2024.06.11 |
화살표 함수(Arrow Function) (1) | 2024.06.11 |
댓글