세트(Set): 자바스크립트에서 고유한 값들의 집합을 다루는 자료구조
이를 활용하면 데이터 중복을 제거하고 유일한 값들을 효과적으로 관리할 수 있음
배열
은 데이터를 순서있게 저장해서 인덱스(index)를 통해서 특정 위치에 저장되어 있는 데이터에 접근이 가능함 또한 배열에는 동일한 값을 여러 번 저장할 수 있음. 값이 동일하더라도 인덱스가 틀리기 때문에 데이터의 중복이 문제되지 않는다.반면에 세트
는 데이터를 순서없이 저장하므로 배열처럼 인덱스를 통해서 접근할 수가 없음. 또한 세트는 중복된 데이터를 허용하지 않는다. 즉, 기존에 세트에 있는 값을 또 추가할 수 없음.
const set = new Set(); // Set(0) {size: 0}
const numSet = new Set([1, 2, 3]); // Set(3) {1, 2, 3}
첫째 줄과 같이 생성자의 인자로 아무 것도 넘기지 않으면 빈 세트가 만들어지며, 아래와 같이 배열을 인수로 넘기면 배열에 담긴 값으로 세트가 만들어짐.
add()
메서드를 사용
set.add(1); // Set(1) {1}
set.add("A"); // Set(2) {1, 'A'}
set.add(true); // Set(3) {1, 'A', true}
아래와 같이 연쇄적으로도 호출 가능
set.add(1).add("A").add(true); // Set(3) {1, 'A', true}
delete()
메서드를 사용
set.delete(1); // true
set.delete(2); // false
delete() 메서드에 인자로 넘기는 값이 세트에 존재하여 성공적으로 삭제하였다면 true를 반환하고, 해당 값이 세트에 존재하지 않아서 삭제에 실패하였다면 false를 반환
has()
메서드를 사용
보통 if 조건문이나 삼항 연산자(ternary operator)와 많이 사용됨
if (set.has("A")) {
console.log("A는 세트에 존재합니다."); // A는 세트에 존재합니다.
}
const result = set.has("B") ? "YES" : "NO"; // NO
size
속성을 사용
console.log(set.size); // 2
clear()
메서드를 사용
set.clear(); // Set(0) {size: 0}
for 루프문 안에서 of 연산자
를 사용하거나 forEach() 함수
사용
for (const num of numSet) {
console.log(num);
}
numSet.forEach((num) => console.log(num));
Set() 생성자의 인자로 해당 배열이 할당된 변수를 넘김
const array = [1, 2, 2, 3, 3, 3];
const set = new Set(array); // Set(3) {1, 2, 3}
대괄호 안에서 세트를 상대로 전개(spread) 연산자
를 사용하거나 Array.from()
함수 사용
const array = [...set]; // [1, 2, 3]
const array = Array.from(set); // [1, 2, 3]
세트는 중복 값을 허용하지 않기 때문에, 배열이나 문자열에서 중복된 값을 제거하는 데에 매우 유용하게 활용됨
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]
여러 개의 세트를 상대로 다음과 같이 합집합, 교집합, 차집합을 구하기
const set1 = new Set([1, 2, 3, 4, 5]);
const set2 = new Set([4, 5, 6, 7, 8]);
// 합집합
const union = new Set([...set1, ...set2]);
console.log([...union]); // [1, 2, 3, 4, 5, 6, 7, 8]
// 교집합
const intersection = new Set([...set1].filter((value) => set2.has(value)));
console.log([...intersection]); // [4, 5]
// 차집합
const difference = new Set([...set1].filter((value) => !set2.has(value)));
console.log([...difference]); // [1, 2, 3]
세트를 생성할 때 저장할 수 있는 자료형을 제한할 수 있음
예를 들어, 다음과 같이 세트를 생성할 때 숫자형의 데이터만 저장할 수 있도록 타입 인자를 명시해주면 다른 자료형의 데이터를 추가하려고 하면 타입 에러가 발생하게 된다.
const numSet = new Set<number>();
numSet.add(1);
numSet.add("A"); // Argument of type 'string' is not assignable to parameter of type 'number'.(2345)
// ^? (method) Set<number>.add(value: number): Set<number>
이러한 타입 안정성과 타입 추론을 통해 좀 더 신뢰할 수 있는 코드를 작성할 수 뿐만 아니라 코드 편집기에서 자동완성의 편리함도 누릴 수 있음