정의 및 사용 방법
Set 객체는 값의 중복을 허용하지 않으며, 인덱스 구조가 없는 고유 값들의 컬렉션(집합)입니다.
특징
Set객체는 배열과는 달리 순서(인덱스)를 가지지 않는 단순한 구조를 가지고 있습니다.- 이 단순한 구조로 인해, 데이터가 많아져도 중복 확인과 관리 처리가 빠릅니다.
- 이 객체의 관련 속성과 메서드를 사용하여 데이터를 효율적으로 관리할 수 있습니다.
- 원시값(문자열, 숫자 등)뿐만 아니라 객체 참조 등 모든 유형의 값을 저장할 수 있습니다.
Set 객체는 데이터 중복 제거와 대용량 데이터의 효율적인 관리를 위해 유용하게 사용됩니다.
Set 객체의 기본적인 사용 방법
Set 객체는 중복되지 않는 고유 값을 저장하며, 배열과는 달리 순서(인덱스)를 가지지 않는 단순한 구조를 가지고 있습니다. 이 객체의 관련 속성과 메서드를 사용하여 데이터를 효율적으로 관리할 수 있습니다.
아래 예제는 Set 객체를 사용하는 기본적인 방법을 보여줍니다. new Set()을 사용하여 Set 객체을 생성하고, .add()을 사용해 값을 추가하고, .size로 객체에 포함되어 있는 값의 개수를 확인하며, .has()으로는 값이 있는지 체크하고, .delete()로는 원하는 값을 제거할 수 있습니다.
/* 1. 빈 Set 객체 생성 */
const emptySet = new Set(); // 아무 값도 없는 빈 Set
console.log(emptySet); // Set(0) {size: 0}
/* 2. 초깃값을 가진 Set 생성
배열을 전달하여 초깃값 설정 */
const numbers = new Set([1, 2, 3, 2, 1]);
console.log(numbers); // Set(3) {1, 2, 3} → 중복 자동 제거
/* 3. 값 추가 */
numbers.add(7);
console.log(numbers); // Set(4) {1, 2, 3, 7}
numbers.add(2); // // 중복되는 값은 추가되지 않음
console.log(numbers); // Set(4) {1, 2, 3, 7}
/* 4. 값 개수 확인 */
console.log(numbers.size); // 4
/* 5. 값이 있는지 체크 */
console.log(numbers.has(1)); // true
console.log(numbers.has(8)); // false
/* 6. 값 삭제 */
numbers.delete(1); // 1 삭제
console.log(numbers); // Set(3) {2, 3, 7}
Set 객체의 유용성
Set 객체는 무엇보다도 데이터 중복 제거와 대용량 데이터의 효율적인 관리에 매우 유용합니다.
데이터 중복 제거
Set 객체의 가장 직관적인 장점은 중복 데이터(값)를 자동으로 제거하는 것입니다. 배열과 비교하면 바로 이해할 수 있습니다.
배열은 같은 값을 여러 번 저장할 수 있어 중복을 제거하려면 복잡한 코드가 필요합니다.
하지만 Set은 생성 시점부터 중복을 자동으로 제거합니다. 또한 Set 객체에 .add()을 사용해 데이터를 추가할 때에도 중복되는 값은 추가되지 않습니다. 이 기능을 활용하면 특히, 배열에 담긴 데이터의 중복을 가장 간결하게 제거할 수 있습니다.
// 배열은 같은 값을 여러 번 저장할 수 있어 중복 제거가 자동으로 되지 않습니다.
const arr = [1, 2, 2, 3, 3];
console.log(arr); // [1, 2, 2, 3, 3]
Set은 생성 시점부터 중복을 자동으로 제거
const arr = [1, 2, 2, 3, 3];
console.log(arr); // [1, 2, 2, 3, 3]
// Set 예제
const uniqueSet = new Set(arr);
console.log(uniqueSet); // Set {1, 2, 3}
Set 객체는 자동으로 중복을 제거하기 때문에 간단하게 고유 값만 관리할 수 있습니다.
대용량 데이터의 효율적인 관리
Set 객체는 인덱스 구조가 없는 단순한 구조의 컬렉션이기 때문에, 데이터가 많아도 빠른 확인과 삭제가 가능합니다. 즉, 대용량 데이터 처리 성능을 빠르게 크게 유지하면서 데이터를 관리할 수 있습니다.
참고하세요!
Set 객체와 달리 배열은 값과 인덱스가 연결되는 데이터 구조입니다. 처리 속도면에서 Set 객체가 배열보다 월등히 빠릅니다.
// 1부터 1,000,000까지 데이터를 가진 Set 객체 생성
const bigSet = new Set();
for (let i = 1; i <= 1000000; i++) {
bigSet.add(i);
}
// 값 존재 확인
console.log(bigSet.has(500000)); // true → 매우 빠르게 확인 가능
// 값 삭제
bigSet.delete(500000);
console.log(bigSet.has(500000)); // false → 빠른 삭제
Set 객체의 빠른 처리 능력은 특히, 여러 작업이 동시에 일어나는 실시간 시스템에서 중요합니다. 대용량 데이터를 다룰 때, 서버의 처리 부담을 줄이고 안정적으로 관리할 수 있는 장점이 있습니다.
Set 객체 생성하기
Set 객체를 생성하는 것은 매우 간단합니다. 먼저 구문를 통해 살펴보겠습니다.
구문
// 1. 빈 Set 객체 생성
new Set()
// 2. 초깃값을 가진 Set 객체 생성
new Set(iterable)
설명
new |
새로운 Set 객체를 생성할 때 반드시 붙여서 실행해야 하는 연산자입니다. |
|---|---|
Set() |
Set 객체를 생성하는 생성자 함수인 Set을 호출하는 의미입니다.
new Set() 형태로 호출하면 빈 Set 객체가 만들어집니다. new 없이 호출하면 TypeError가 발생합니다. |
Set(iterable) |
new Set(iterable) 형태로 호출하면 초깃값이 있는 Set 객체를 생성할 수 있습니다.
|
예제
// 1) 빈 Set 객체 생성
const emptySet = new Set();
console.log(emptySet); // 출력: Set(0) {size: 0}
// 2) 이터러블(iterable)인 배열을 전달해 초깃값을 가진 Set 생성
const initializedSet = new Set([
"apple",
"banana",
"orange"
]);
console.log(initializedSet); // 출력: Set(3) {'apple', 'banana', 'orange'}
Set 객체 다루기
new 연산자로 생성한 Set 객체는 관련 속성과 메서드가 내장되어 있습니다. 이 속성과 메서드를 사용하면 Set 객체를 쉽고 효율적으로 다룰 수 있습니다.
속성
Set 객체에는 여러 관련 속성들이 있습니다. 여기에서는 대표적인 속성인 .size에 대해 알아보겠습니다.
.size
이 속성은 해당 Set 객체의 값 개수를 반환합니다.
특히 중복이 자동으로 제거되는 Set 객체의 특성상, .size는 고유한 값의 수를 확인하거나 반복 처리 시 매우 유용합니다.
// Set 객체 생성
const mySet = new Set();
// 값 추가
mySet.add("apple");
mySet.add("banana");
mySet.add("orange");
// size 속성으로 값 개수 확인
console.log(mySet.size); // 출력: 3
// 값 하나 삭제
mySet.delete("banana");
console.log(mySet.size); // 출력: 2
// 모든 값 삭제
mySet.clear();
console.log(mySet.size); // 출력: 0
메서드
Set 객체는 값(데이터)를 추가, 조회, 삭제, 순회하는 기능을 위한 다양한 메서드가 내장되어 있습니다.
다음은 Set 객체의 대표적인 메서드를 정리한 표입니다.
.add(value) |
Set에 새로운 값(value)을 추가합니다. 이미 존재하는 값이라면 추가되지 않습니다. |
|---|---|
.has(value) |
특정 값이 Set에 존재하는지 확인합니다.
value가 Set에 존재하면 true, 그렇지 않으면 false를 반환합니다. |
.delete(value) |
Set에서 해당 값(value)을 삭제합니다 |
.clear() |
Set의 모든 값을 삭제합니다. |
.forEach() |
Set의 각 값에 대해 삽입 순서대로 한 번씩 순서대로 순회해서 콜백 함수로 처리합니다. |
메서드들의 구현 방식을 예제를 통해 살펴보겠습니다.
// Set 객체 생성
const mySet = new Set();
// .add(value)로 값 추가
mySet.add("apple");
mySet.add("banana");
// .has(value)로 값 확인
console.log(mySet.has("apple")); // 출력: true
// .delete(value)로 값 삭제
mySet.delete("banana");
console.log(mySet.has("banana")); // 출력: false
// clear()로 전체 값 삭제
mySet.clear();
console.log(mySet.size); // 출력: 0
// .forEach()로 Set 순회
mySet.add("apple");
mySet.add("orange");
mySet.forEach((value) => {
console.log(value);
});
// 출력:
// apple
// orange
Set 객체의 순회
Set 객체는 인덱스(순서)를 가지지 않지만, for...of 문으로 순회할 수 있는 Iteration Protocols가 적용된 객체입니다.
또한, 전용 .forEach() 메서드와 스프레드 구문(...)을 사용할 수 있습니다.
for...of 문을 사용한 순회
for...of 문을 사용하면 Set 객체에 추가된 순서대로 값에 접근할 수 있습니다.
const fruits = new Set(["사과", "바나나", "포도"]);
// Set 객체에 값이 추가된 순서대로 요소를 하나씩 꺼내 사용합니다.
for (const item of fruits) {
console.log(item);
}
// 출력:
// 사과
// 바나나
// 포도
.forEach() 메서드를 사용한 순회
Set 객체의 .forEach() 메서드는 각 값을 콜백 함수에서 처리할 수 있습니다.
콜백 함수의 매개변수에는 순회에 해당하는 값을 전달할 수 있습니다.
const animals = new Set(["Dog", "Cat", "Fish"]);
// 콜백 함수에 Set의 값이 전달되어, 각 요소를 처리합니다.
animals.forEach((value) => {
console.log(`현재 처리 중인 값: ${value}`);
});
// 출력:
// 현재 처리 중인 값: Dog
// 현재 처리 중인 값: Cat
// 현재 처리 중인 값: Fish
스프레드 구문(...)을 사용한 순회
스프레드 구문(...)을 사용하면 Set 객체을 쉽게 배열로 변환할 수 있어, 배열 메서드와 함께 활용 가능합니다.
const letters = new Set(["a", "b", "c"]);
const lettersArray = [...letters].map(l => l.toUpperCase());
console.log(lettersArray); // 출력: ["A", "B", "C"]
코드 부연설명
map() 함수는 배열의 각 요소에 주어진 콜백 함수를 적용해 새로운 배열을 반환합니다. 이때, 원본 배열은 변경되지 않습니다.
Set 객체의 배열 변환
Set 객체는 배열과 달리 인덱스를 가지지 않지만, 필요할 때 배열로 변환해 활용할 수 있습니다. 변환은 스프레드 구문(...)과 Array.from() 함수를 사용하는 방법 두 가지가 있습니다.
스프레드 구문(...)을 사용한 배열 변환
const letters = new Set(["a", "b", "c"]);
// Set → 배열 변환
const lettersArray = [...letters];
console.log(lettersArray); // 출력: ["a", "b", "c"]
Array.from()을 사용한 배열 변환
const numbers = new Set([1, 2, 3]);
// Set → 배열 변환
const numbersArray = Array.from(numbers);
console.log(numbersArray); // 출력: [1, 2, 3]
Set 객체의 집합 연산 메서드
Set 객체는 수학적 집합의 연산과 유사하게 값을 다룰 수 있는 다양한 메서드를 제공합니다.
이 메서드들을 활용하면 교집합, 합집합, 차집합뿐만 아니라, 부분집합 여부나 상위집합 여부 등을 쉽게 확인할 수 있습니다. 아래에서 소개하는 메서드들은 모두 Set 객체를 반환하거나 Boolean 값을 반환하므로, 조건 확인과 값 관리에 매우 유용합니다.
해당 메서드을 클릭하면 MDN(Mozilla Developer Network)에서 제공하는 관련 상세 정보(영문)를 볼 수 있습니다.
| 메서드 | 반환값 타입 | 수학적 의미 | 설명 |
|---|---|---|---|
A.difference(B) |
Set |
집합 A에서 B에 포함되지 않은 값들의 집합(집합 A와 B의 차집합)을 반환합니다. | |
A.intersection(B) |
Set |
집합 A와 B에 모두 포함된 값들의 집합(집합 A와 B의 교집합)을 반환합니다. | |
A.symmetricDifference(B) |
Set |
집합 A 또는 B에만 포함된 값들의 집합(대칭차집합)을 반환합니다. | |
A.union(B) |
Set |
집합 A와 B를 합친 집합(집합 A와 B의 합집합)을 반환합니다. | |
A.isDisjointFrom(B) |
Boolean |
집합 A와 B가 서로 공집합인지 확인합니다(겹치는 값이 없으면 true). |
|
A.isSubsetOf(B) |
Boolean |
집합 A가 집합 B의 부분집합인지 확인합니다(모든 값이 B에 포함되어 있으면 true). |
|
A.isSupersetOf(B) |
Boolean |
집합 A가 집합 B의 상위집합인지 확인합니다(B의 모든 값이 A에 포함되어 있으면 true). |
활용 예제
웹 서버에서는 동일한 사용자가 여러 번 요청을 보내더라도 중복 없이 고유 방문자를 계산해야 하는 경우가 많습니다. 이때, Set 객체의 “고유 값만 유지하는 특성”을 그대로 활용할 수 있습니다.
고유 방문 IP 집계
// 요청을 보낸 IP를 저장하는 Set 객체
const visitorIPs = new Set();
// 사용자가 들어올 때마다 호출되는 함수
function recordVisit(ip) {
visitorIPs.add(ip); // 중복되는 IP는 자동으로 제거됨
console.log(`현재 기록된 고유 IP 수: ${visitorIPs.size}`);
}
// 여러 IP가 섞여 반복 방문하는 상황
recordVisit("192.168.0.10");
recordVisit("192.168.0.11");
recordVisit("192.168.0.10"); // 중복 처리됨
recordVisit("192.168.0.12");
recordVisit("192.168.0.11"); // 중복 처리됨
// 최종 고유 방문자 수 확인
console.log(`최종 집계된 고유 방문 IP 수: ${visitorIPs.size}개`);
console.log(visitorIPs);
현재 기록된 고유 IP 수: 1
현재 기록된 고유 IP 수: 2
현재 기록된 고유 IP 수: 2
현재 기록된 고유 IP 수: 3
현재 기록된 고유 IP 수: 3
최종 집계된 고유 방문 IP 수: 3개
Set { "192.168.0.10", "192.168.0.11", "192.168.0.12" }
명세서
| 명세서 사양 | |
|---|---|
Set
|
ECMAScript® 2026 Language Specification #sec-set-objects |
호환성
| 객체 |
데스크탑 Chrome
|
데스크탑데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
Node.js
|
|---|---|---|---|---|---|
Set
|
예 | 예 | 예 | 예 | 0.12 |
Set() 생성자 |
예 | 예 | 예 | 예 | 0.12 |
new Set(iterable)
|
예 | 예 | 예 | 예 | 0.12 |
.size
|
예 | 예 | 예 | 예 | 0.12 |
.add(value)
|
예 | 예 | 예 | 예 | 0.12 |
.has(value)
|
예 | 예 | 예 | 예 | 0.12 |
.delete(value)
|
예 | 예 | 예 | 예 | 0.12 |
.clear()
|
예 | 예 | 예 | 예 | 0.12 |
.forEach()
|
예 | 예 | 예 | 예 | 0.12 |
A.difference(B)
|
122 | 122 | 127 | 17 | 22 |
A.intersection(B)
|
122 | 122 | 127 | 17 | 22 |
A.symmetricDifference(B)
|
122 | 122 | 127 | 17 | 22 |
A.union(B)
|
122 | 122 | 127 | 17 | 22 |
A.isDisjointFrom(B)
|
122 | 122 | 127 | 17 | 22 |
A.isSubsetOf(B)
|
122 | 122 | 127 | 17 | 22 |
A.isSupersetOf(B)
|
122 | 122 | 127 | 17 | 22 |