HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🐣
프론트엔드 데브코스 3기 교육생
/
📚
3기 스터디 가이드
/
💯
자바스크립트 Deep Dive 스터디
/
🕤
자바스크립트 Deep Dive
/
💵
37장 Set과 Map - 지영님
💵

37장 Set과 Map - 지영님

set

: 중복되지 않는 유일한 값들의 집합
구분
배열
Set 객체
동일한 값을 중복하여 포함할 수 있다.
O
X
요소 순서에 의미가 있다.
O
X
인덱스로 요소에 접근할 수 있다.
O
X
⇒ 이러한 Set 객체는 수학적 집합 특성과 일치
: 교집합, 여집합, 합집합, 차집합 등 구현 가능
 

set 객체의 특성

  • Set 생성자 함수로 생성. 인수를 전달하지 않으면 빈 객체가 생성된다.
const set = new Set(); console.log(set); //Set(0){}
 
  • 이터러블을 인수로 전달받아 set객체 생성. 중복된 값은 저장되지 않는다!
const set1 = new Set([1, 2, 3, 3]); console.log(set1); const set2 = new Set('hello'); console.log(set2); //set(4) {'h', 'e', 'l', 'o'}
 
⇒ 이러한 특성을 사용해서 배열의 중복된 요소를 제거할 수 있다.
notion image
 

요소 개수 확인

→ Set.prototype.size 프로퍼티 사용
const {size} = new Set([1,2 ,3 ,3]); console.log(size) = 3
size 프로퍼티는 setter 없이 getter 함수만 존재하는 접근자 프로퍼티
→ 숫자를 할당하여 요소 개수를 변경하는 것은 불가능
 
 

요소 추가

→ Set.prototype.add 메서드 사용
const set = new Set(); console.log(set); //Set(0) {} set.add(1); console.log(set); //Set(1) {1}
 
add 메서드는 요소가 추가된 set 객체를 반환하기 때문에 연속적 호출이 가능하다.
const set = new Set(); set.add(1).add(2); console.log(set); //Set(2) {1, 2}
→ 중복된 요소를 추가할 경우 에러가 발생하지 않고 무시된다.
 
const set = new Set(); conosle.log(NaN === NaN); //false conosle.log(0 === -0); //true set.add(NaN).add(NaN); console.log(set); //Set(1) {NaN} set.add(0).add(-0) console.log(set); //Set(2) {NaN, 0}
  • 일치 비교 연산자(===)를 사용하면 NaN과NaN은 다르다고 평가된다.
⇒ Set 객체에서는 같다고 평가하여 중복 추가 허용X
⇒+0, -0역시 같다고 평가하여 중복 추가 허용X
 
 

요소 존재 여부 확인

→ Set.prototype.has 메서드를 사용. 특정 요소의 존재여부에 대해 불리언 값을 반환
const set = new Set([1, 2, 3]); console.log(set.has(2))// true console.log(set.has(4))// false
 
 

요소 삭제

→ Set.prototype.delete 메서드를 사용. 삭제 성공 여부를 나타내는 불리언 값을 반환
⇒ Set 객체는 인덱스를 갖지 않기 때문에 요소값을 인수로 전달해야 한다.
const set = new set([1,2,3]); set.delete(2); console.log(set);//Set(2) {1, 3}
존재하지 않는 요소를 삭제하려고 한다면 에러가 나지 않고 무시된다.
 
💡
delete는 add와 달리 불리언을 반환하기 때문에 연속적으로 호출할 수 없다!
 
 

요소 일괄 삭제

→ Set.prototype.clear 메서드를 사용. 언제나 undefined를 반환한다.
const set = new Set([1, 2, 3]); set.clear(); console.log(set); Set(0) {}
 
 

요소순회

→ Set.prototype.forEach 메서드를 사용
  • 첫 번째 인수: 현재 순회 중인 요소 값
  • 두 번째 인수: 현재 순회 중인 요소 값
  • 세 번째 인수: 현재 순회 중인 Set 객체 자체
 
첫 번째 인수와 두 번째 인수는 같은 값은 갖는데 이는 Array.prototype.forEach 메서드와 인터페이스를 통일하기 위함일 뿐 다른 의미는 없다.
Array.prototype.forEach 메서드의 콜백 함수는 두 번째 인수로 현재 순회 중인 인덱스를 전달받는데 Set 객체는 순서에 의미가 없기 때문에 배열과 같이 인덱스를 갖지 않는다.
const set = new Set([1, 2, 3]); set.forEach((v, v2, set) => console.log(v, v2, set)); /* 1 1 Set(3) {1, 2, 3} 2 2 Set(3) {1, 2, 3} 3 3 Set(3) {1, 2, 3} */
 
→ Set 객체는 이터러블이기 때문에 for…of문 순회가 가능하며 스프레드 문법과 배열 디스트럭처링 할당의 대상이 될 수 있다.
💡
Set 객체는 요소 순서에 의미를 갖지 않지만 순회하는 순서는 요소가 추가된 순서로 진행된다. 이는 다른 이터러블의 순회와 호환성을 유지하기 위함이다.
 
 

집합 연산

→ 교집합, 차집합, 합집합 등을 구현할 수 있다.
 

교집합

집합A와 집합B의 공통요소
notion image
Set.prototype.intersection = function(set) { return new Set([...this].filter(v => set.has(v))); } const setA = new Set([1, 2, 3, 4]); const SetB = new Set([2, 4]); console.log(setA.intersection(setB)); //Set(2) {2, 4} console.log(setB.intersection(setA)); //SEt(2) {2, 4}
 
 

합집함

집합A와 집합B의 중복 없는 모든 요소로 구성
notion image
 
Set.prototype.union = function (set) { return new Set([...this, ...set]); } const setA = new Set([1, 2, 3, 4]); const setB = new Set([2, 4]); console.log(setA.union(setB)); //Set(4) {1, 2, 3, 4}; console.log(setB.union(setA)); //Set(4) {2, 4, 1, 3};
 
 

차집합

집합 A에는 존재하지만 집합 B에는 존재하지 않는 요소로 구성
 
첫 번째 방법
첫 번째 방법
두 번째 방법
두 번째 방법
 
 

부분 집합과 상위 집합

부분집합: 집합A가 집합B에 포함되는 경우
→ 이 때 집합 B가 집합A의 상위 집합
첫 번째 방법
첫 번째 방법
notion image
 

Map

키와 값의 쌍으로 이루어진 컬렉션
구분
객체
Map 객체
키로 사용할 수 있는 값
문자열 또는 심벌 값
객체를 포함한 모든 값
이터러블
X
O
요소 개수 확인
Object.keys(obj).length
map.size
 

Map 객체 생성

→ Map 생성자 함수로 생성. 인수를 전달하지 않으면 빈 Map 객체가 생성
const map = new Map(); console.log(map); //Map(0) {}
 
  • Map 생성자 함수는 이터러블을 인수로 전달받아 Map 객체를 생성.
⇒ 이 때 인수로 전달되는 이터러블은 키와 값의 쌍으로 이루어진 요소로 구성되어야 한다.
const map1 = new Map([['key1', 'value1'], ['key2', 'value2']]); console.log(map1); //Map(2) {'key1' => 'value1', 'key2' => 'value2'}; const map2 = new Map([1, 2]); //X, TypeError const map2 = new Map([[1, 2]]); // O
 
⇒중복된 키를 갖는 요소가 존재하면 값이 덮어써진다.
 

요소 개수 확인

→ Map.prototype.size 프로퍼티 사용
const {size} = new Map([['key1', 'value1'], ['key2', 'value2']]); console.log(size); //2
setter없이 getter만 존재하는 접근자 프로퍼티이기 때문에 숫자를 할당하여 개수를 변경할 수 없다.
 

요소 추가

→ Map.prototype.set 메서드를 사용
const map = new Map(); console.log(map) //Map(0) {} map.set('key1', 'value1'); console.log(map) //Map(1) {'key1' => 'value1'}
set메서드는 새로운 요소가 추가된 Map 객체를 반환하기 때문에 연속적으로 사용이 가능하다.
 
const map = new Map(); map .set('key1', 'value1') .set('key2', 'value2'); console.log(map); //Map(2) {'key1' => 'value1', 'key2' => 'value2'}
중복된 키를 갖는 요소가 존재할 수 없기 때문에 중복된 키를 갖는 요소를 추가하면 값이 덮어써진다.
 
  • Set과 동일하게 NaN과 NaN을 같다고 평가하여 중복 추가를 허용하지 않음. +0, -0도 마찬가지로 같은 값으로 평가
const map = new Map(); console.log(NaN === NaN); //false console.log(0 === -0); //true map.set(NaN, 'value1').set(NaN, 'value2'); console.log(map) //Map(1) {NaN => 'value2'};
 
  • 객체는 키로 문자열 또는 심벌만 사용가능했지만 Map 객체는 타입 제한이 없다. 모든 값을 키로 사용할 수 있다.
const map = new Map(); const lee = {name: 'Lee'}; const kim = {name: 'Kim'}; map .set(lee, 'developer') .set(kim, 'designer'); console.log(map); //Map(2) {{name: 'Lee'} => 'developer', {name: 'Kim'} => 'designer'}
 

요소 취득

→ Map.prototype.get 메서드를 사용. 인수로 키를 전달하면 Map 객체에서 키를 갖는 값을 반환. 존재하지 않으면 undefined 반환
const map = new map(); const lee = {name: 'Lee'}; const kim = {name: 'Kim'}; map .set(lee, 'developer') .set(kim, 'designer'); console.log(map.get(lee)); //developer console.log(map.get('key')); //unedfined
 
 

요소 존재 여부 확인

→ Map.prototype.has 메서드를 사용. 특정 요소의 존재여부를 나타내는 불리언 값을 반환
const lee = {name: 'Lee'}; const kim = {name: 'Kim'}; const map = new Map([[lee, 'developer'], [kim, 'designer']]); console.log(map.has(lee)); //true console.log(map.has('key')); //false
 
 

요소 삭제

→ Map.prototype.delete 메서드를 사용. 삭제 성공 여부를 나타내는 불리언 값 반환
const lee = {name: 'Lee'}; const kim = {name: 'Kim'}; const map = new Map([[lee, 'developer'], [kim, 'designer']]); map.delete(kim); console.log(map); //Map(1) {{name: 'Lee'} => 'developer'}
 
  • 존재하지 않는 키를 삭제하려고 하면 에러 없이 무시된다.
  • 삭제 성공 여부를 나타내는 불리언 값을 반환하기 때문에 연속적으로 호출하여 사용할 수 없다.
 
 

요소 일괄 삭제

→ Map.prototype.clear 메서드를 사용. 언제나 undefined 반환
const lee = {name: 'Lee'}; const kim = {name: 'Kim'}; const map = new Map([[lee, 'developer'], [kim, 'designer']]); map.clear(); console.log(map); //Map(0) {}
 
 

요소 순회

→ Map.prototype.forEach 메서드를 사용
  • 첫 번째 인수: 현재 순회 중인 요소값
  • 두 번째 인수: 현재 순회 중인 요소키
  • 세 번째 인수: 현재 순회 중인 Map 객체 자체
 
notion image
 
Map 객체는 이터러블이므로 for…of 순회할 수 있으며, 스프레드 문법과 배열 디스트럭처링 할당의 대상이 될 수 있다.
 
Map 객체는 이터러블이면서 동시에 이터레이터 객체를 반환하는 메서드를 제공
Map 메서드
설명
Map.prototype.keys
Map 객체에서 요소키를 값으로 갖는 이터러블이면서 동시에 이터레이터인 객체를 반환
Map.prototype.values
Map 객체에서 요소값를 값으로 갖는 이터러블이면서 동시에 이터레이터인 객체를 반환
Map.prototype.entries
Map 객체에서 요소키와 요소값를 값으로 갖는 이터러블이면서 동시에 이터레이터인 객체를 반환
notion image
 
→ Map 객체는 요소의 순서에 의미를 갖진 않지만 순회하는 순서는 요소에 추가된 순서를 따른다. 다른 이터러블의 순회와 호환성을 유지하기 위함이다.