반응형
Set이란?
Set 객체는 중복되지 않는 유일한 값들의 집합입니다. Set 객체는 배열과 비슷하지만 차이점이 존재합니다.
배열 | Set 객체 | |
동일한 값을 중복하여 포함 가능하다. | O | X |
요소 순서가 의미가 있다. | O | X |
인덱스로 요소에 접근할 수 있다. | O | X |
위의 특성으로 보아 Set 객체는 수학적 집합의 특성과 일치하며, 교집합, 합집합, 차집합, 여집합 등을 구현할 수 있습니다.
Set 객체 생성
- Set 생성자 함수로 Set 객체를 생성합니다.
- 생성자 함수에 인자를 전달하지 않으면 빈 Set 객체가 생성됩니다.
const set = new Set();
console.log(set); // Set(0) {}
- Set 생성자 함수는 이터러블을 인수로 전달받아 Set 객체를 생성하는데, 이때 이터러블의 중복된 값은 Set 객체에 저장되지 않습니다.
const set1 = new Set([1, 1, 2, 2, 3]);
const set2 = new Set('aabbcc');
console.log(set1); // Set(3) {1,2,3}
console.log(set2); // Set(3) {"a", "b", "c"}
- Set 객체의 특성을 사용하여 배열에서 중복된 요소를 제거할 수 있습니다.
const arr = [1, 2, 1, 2, 3, 4, 3];
const uniq = array => [...new Set(array)];
console.log(uniq(arr)); // [1, 2, 3, 4];
요소 개수 확인하기
- Set.prototype.size 프로퍼티를 사용하여, Set 객체의 요소 수를 반환합니다.
const { size } = new Set([1, 2, 2, 3]);
console.log(size); // 3
- size 프로퍼티는 setter 없이 getter 함수만 존재하는 접근자 프로퍼티입니다. 그래서 size 프로퍼티에 숫자 할당을 시도해도, Set 객체의 요소 개수는 변경되지 않습니다.
set.size = 10; // size 프로퍼티에 할당을 시도 -> 무시됨
console.log(size) // 3
요소 추가
- Set.prototype.add 메서드를 사용하여, Set 객체에 요소를 추가합니다. 중복된 요소는 추가되지 않습니다.
const set = new Set();
set.add(1);
console.log(set); // Set(1) {1}
- add 메서드를 호출한 후에 add 메서드를 연속 호출(method chaining)할 수 있습니다. add 메서드는 새로운 요소가 추가된 Set 객체를 반환하기 때문입니다.
const set = new Set();
set.add(1).add(2);
console.log(set); // Set(2) {1, 2}
- Set 객체는 자바스크립트의 모든 값을 요소로 저장할 수 있습니다.
const set = new Set();
set
.add(1)
.add('a')
.add(true)
.add(undefined)
.add(null)
.add({})
.add([])
.add(()=>{});
요소 존재 여부 확인
- Set.prototype.has 메서드를 사용하여, Set 객체에 특정 요소가 있는지를 확인합니다.
- boolean 타입(true/false)의 값을 반환합니다.
const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true
console.log(set.has(0)); // false
요소 삭제
- Set.prototype.delete 메서드를 사용하여, Set 객체에서 특정 요소를 삭제합니다.
- 이 때, 삭제하려는 요소의 인덱스가 아닌, 값을 인수로 전달해야 합니다. Set 객체에는 인텍스가 없기 때문입니다.
- 존재하지 않는 Set 객체의 요소를 삭제 시도하면 무시됩니다.
cosnt set = new Set([1, 2, 3]);
set.delete(2); // 요소 2 삭제
console.log(set); // Set(2) {1, 3}
set.delete(1); // 요소 1 삭제
console.log(set); // Set(1) {3}
set.delete(0); // 요소 0 삭제 시도 -> 무시됨
console.log(set); // Set(1) {3}
요소 일괄 삭제
- Set.prototype.clear 메서드를 사용하여, Set 객체에서 모든 요소를 삭제합니다.
const set = new Set([1, 2, 3]);
set.clear();
console.log(set); // Set(0) {}
요소 순회
forEach(data, key, array) 메소드
- Set.prototype.forEach 메서드를 사용하여, Set 객체의 요소를 순회합니다.
- forEach 메서드의 콜백 함수 내부에서 this로 사용될 객체를 인수로 전달한다.
- 이때 콜백 함수는 3개의 인수를 전달받는데, 1번째 인수와 2번째 인수는 같은 값이다. Array.prototype.forEach 메서드와 인터페이스를 통일하기 위함이다.
- 1번째 인수: 현재 순회 중인 요소값
- 2번째 인수: 현재 순회 중인 요소값
- 3번째 인수: 현재 순회 중인 Set 객체
const set = new Set([1, 2, 3]);
set.forEach((value, value2, set) => {
console.log(value, value2, 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 문으로 순회할 수 있고, 전개연산자(spread 문법) 사용이 가능하고, 배열 디스트럭쳐링(destructuring)의 대상이 될 수 있다.
const set = new Set([1, 2, 3]);
// Set 객체는 Set.prototype의 Symbol.iterator 메소드를 상속받는 이터러블이다.
console.log(Symbol.iterator in set); // true
// for...of 문 순회
for (const v of set) {
console.log(v); // 1 2 3
}
// spread
console.log(...set); // [1, 2, 3]
// destructure
const [a, ...rest] = set;
console.log(a, rest); // 1, [2, 3]
집합 연산
- 교집합
// 방법 1
Set.prototype.intersection = function (set) {
const result = new Set();
for (const v of set) {
// 공통되는 요소라면 교집합의 대상
if (this.has(v)) result.add(v);
}
return result;
}
// 방법 2
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]);
// setA, setB의 교집합
console.log(setA.intersection(setB)); // Set(2) {2, 4}
- 합집합
// 방법 1
set.prototype.union = function (set) {
// this(Set 객체)를 복사
const result = new Set(this);
for (const v of set) {
// 모든 요소는 합집합의 대상
result.add(v);
}
return result;
}
// 방법 2
set.prototype.union = function (set) {
return new Set([...this, ...set]);
}
const setA = new Set([1, 2, 3, 4]);
const setB = new Set([1, 3]);
// setA, setB의 합집합
console.log(setA.union(setB)) // Set(4) {1, 2, 3, 4}
- 차집합
// 방법 1
Set.prototype.difference = function (set) {
// this(Set 객채)를 복사
const result = new Set(this);
for (const v of set) {
// 한 집합에는 존재하지만, 다른 집합에는 존재하지 않는 요소라면 차집합의 대상
result.delete(v);
}
return result;
};
// 방법 2
Set.prototype.difference = 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.difference(setB)); // Set(2) {1, 3}
console.log(setB.difference(setA)); // Set(0) {}
- 부분집합(subset), 상위집합(superset)
// 방법 1
Set.prototype.isSuperset = function (subset) {
for (const v of subsest) {
// superset의 모든 요소가 subset을 포함하는지 확인
if(!this.has(v)) return false;
}
return true;
}
// 방법 2
Set.prototype.isSuperset = function (subset) {
const supersetArr = [...this];
return [...subset].every(v => supersetArr.includes(v));
}
const setA = new Set([1, 2, 3, 4]);
const setA = new Set([1, 2]);
console.log(setA.isSuperset(setB)); // true
console.log(setB.isSuperset(setA)); // false
✏️ 모던 자바스크립트 Deep Dive 도서를 읽고 개인적으로 공부하며 정리한 내용입니다.
반응형
'Programming > JavaScript' 카테고리의 다른 글
[JavaScript] Moment.js 사용법 (현재 날짜, 날짜 포맷, 날짜 비교) (0) | 2023.06.23 |
---|---|
[JavaScript] e.preventDefault()와 e.stopPropagation()의 차이점 (2) | 2023.01.05 |
[Node.js] Node.js 입력 받는 방법, 표준입출력 (0) | 2020.03.18 |
[jQuery] jQuery 요소 찾기, 텍스트 바꾸기, 요소 변경/생성 (0) | 2019.12.22 |
[Node.js] Node.js로 서버 구축하기 (0) | 2019.12.22 |
댓글