본문 바로가기
Javascript/javascript Core

[Javascript 강의] 18강 Set과 Map

by 카리3 2022. 2. 5.

Set과 Map

 

Set

Set 객체는 중복되지 않는 유일한 값들의 집합이다. 배열과 유사하지만 다음과 같은 차이가 있다
1. 동일한 값을 중복하여 포함할 수 없다
2. 요소 순서에 의미가 없다
3. 인덱스로 요소에 접근할 수 없다.
Set 객체의 특성은 수학적 집합의 특성과 일치한다. Set은 수학적 집합을 구현하기 위한 자료구조다. 따라서 Set을 통해 교집합, 합집합, 차집합, 여집합 등을 구현할 수 있다.

#Set 객체의 생성
const set = new Set();
console.log(set); //Set(0){}

const set1 = new Set([1,2,3,3]);
console.log(set1); //Set(3)[1,2,3]

//배열의 중복 요소 제거
const uniq = array => array.filter(v,i,self) => self.indexOf(v) === i);
console.log(uniq([2,1,2,3,4,3,4])); //[2,1,3,4]

//Set을 사용한 배열의 중복 요소 제거
const uniq = array => [...new Set(array)];
console.log(uniq([2,1,2,3,4,3,4])); //[2,1,3,4]

#요소 개수 확인
const set = new Set([1,2,3,3]);
set.size = 10; //무시된다, setter 함수가 존재하지 않음
console.log(set.size); //3

#요소 추가
const set = new Set();
set.add(1).add(2).add(2);
console.log(set); //Set(2)[1,2]
//Set 객에는 객체나 배열과 같이 자바스크립트의 모든 값을 요소로 저장할 수 있다.

#요소 존재 여부 확인
console.log(set.has(2)); //true

#요소 삭제
set.delete(2);  //불리언 값을 반환한다.

#요소 일괄 삭제
set.clear();

#요소 순회
const set = new Set([1,2,3]);
//첫 번째 인수: 현재 순회 중인 요소값
//두 번째 인수: 현재 순회 중인 요소값
//세 번째 인수: 현재 순회 중인 Set 객체 자체
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 객체는 이터러블이다
console.log(Symbol.iterator in set); //true

//이터리블인 Set 객체는 for...of 문으로 순회할 수 있다.
for(const value of set){
 console.log(value); //1 2 3
}

//이터러블인 Set 객체는 스프레드 문법의 대상이 될 수 있다.
console.log([...set]); //[1,2,3]

//이터러블인 Set 객체는 배열 디스트럭처링 할당의 대상이 될 수 있다.
const[a, ...rest] = set;
console.log(a, rest); // 1, [2,3]

집합연산

#교집합
예제1)
Set.prototype.intersection = function(set){
  const result = new Set();  
  for(const value of set){
   //2개의 set의 요소가 공통되는 요소이면 교집합의 대상이다.
   if(this.has(value)) result.add(value);
  }
  return result;
};

예제2)
Set.prototype.intersection = function(set){
 return new Set([...this].filter(v=>set.has(v)));
}

#합집합
예제1)
Set.prototype.union = function(set){
 const result = new Set(this); 
 for(const value of set){
  result.add(value);
 }
};

예제2)
Set.prototype.union = function(set){
 return new Set([...this, ...set]);
};

#차집합
예제1)
Set.prototype.difference = function(set){
 const result = new Set(this);
 for(const value of set){
  result.delete(value);
 }
};

예제2)
Set.prototype.difference = function(set){
  return new Set([...this].filter( v => !set.has(v)));
};

 

Map

Map 객체는 키와 값의 쌍으로 이루어진 컬렉션이다. Map 객체는 객체와 유사 하지만 다음과 같은 차이가 있다.

구분 객체 Map 객체
키로 사용할 수 있는 값 문자열, 심벌값 객체를 포함한 모든 값
이터러블 X O
요소 개수 확인 Object.keys(obj).length map.size
#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]); //TypeError: Iterator value 1 is not an entry object

//중복된 키를 갖는 요소가 존재하면 값이 덮어써진다.
const map = new Map([["key1","value1"],["key1","value2"]]);
console.log(map); // Map(1) {"key1"=>"value2"}

#요소 개수 확인
console.log(map.size); //1

#요소 추가
const map = new Map();
map.set("key1","value1")
   .set("key2","value2");
console.log(map); // Map(2) {"key1"=>"value1", "key2"=>"value2"}

#요소 취득
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

#요소 존재 여부 확인
map.has(lee); //true

#요소 삭제
map.delete(kim); //true

#요소 일괄 삭제
map.clear();

#요소 순회
const map = new Map();
const lee = {name:'Lee'};
const kim = {name:'Kim'};

map.set(lee, 'developer')
   .set(kim, 'designer');
//첫번째 인수: 현재 순회 중인 요소값
//두번째 인수: 현재 순회 중인 요소키
//세번째 인수: 현재 순회 중인 Map 객체 자체
map.forEach(v, k, map) => console.log(v, k, map);

//Map 객체는 이터러블이다.
console.log(Symbol.iterator in map); //true

//이터러블인 Map 객체는 for...of 문으로 순회할 수 있다.
for(const entry of map){
 console.log(entry);
}

//이터러블인 Map 객체는 스프레드 문법의 대상이 될 수 있다.
console.log([...map]);
//[[{name:'Lee'},'developer'],[{name:'Kim'},'designer']]

//이터러블인 Map 객체는 배열 디스트럭처럼 할당의 대상이 될 수 있다.
const [a,b] = map;
console.log(a,b); //[{name:'Lee'},'developer'] [{name:'Kim'},'designer']

//Map.prototype.keys
for(const key of map.keys()){
 console.log(key);  // {name: "Lee"} {name: "Kim"}
}

//Map.prototype.values
for(const value of map.values()){
 console.log(value);  // developer designer
}

//Map.prototype.entries
for(const entry of map.entries()){
 console.log(entry);  // [{name:'Lee'},'developer'] [{name:'Kim'},'designer']
}