My Boundary As Much As I Experienced

자바스크립트의 Set 자료구조의 특징 및 활용 케이스 본문

FrontEnd/Javascript(Vanilla)

자바스크립트의 Set 자료구조의 특징 및 활용 케이스

Bumang 2024. 3. 24. 04:18

자바스크립트의 Set 자료구조는 한 마디로 '중복을 허용하지 않는 배열'이다.

Set 객체는 배열과 유사하지만 다음과 같은 차이가 있다.

구분 배열 Set 객체
동일 값 중복 가능하다. 불가능하다.
요소 순서에 의미가 있다. (index) 있다. 없다.
인덱스로 요소에 접근 가능하다. 가능하다. 불가능하다.

 

아래는 Set 객체의 기본적인 사용법(생성, 추가, 삭제, 특정 인자 존재 여부 체크, 사이즈 체크 방법)들이다.

 

Set 객체의 생성

아래와 같이 생성자의 인자로 아무 것도 넘기지 않으면 빈 세트가 만들어진다.

 

const set = new Set(); // Set(0) {size: 0}

 

또한 아래와 같이 배열을 인수로 넘기면 배열에 담긴 값으로 세트가 만들어진다.

const numSet = new Set([1, 2, 3]); // Set(3) {1, 2, 3}

const set = new Set(...[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}

 

참고로 add() 메서드는 값을 추가한 후에 세트를 반환하기 때문에 아래와 같이 연쇄적으로 호출할 수도 있다.

set.add(1).add("A").add(true); // Set(3) {1, 'A', true}

 

값 삭제

Set의 delete() 메서드를 사용하면 세트로 부터 특정 값을 삭제할 수 있다. delete() 메서드에 인자로 넘기는 값이 세트에 존재하여 성공적으로 삭제하였다면 true를 반환하고, 해당 값이 세트에 존재하지 않아서 삭제에 실패하였다면 false를 반환한다.

set.delete(1); // true
set.delete(2); // false

 

값 존재 여부 확인

세트에 특정 값이 존재하는지 확인하려면 has() 메서드를 사용한다.

true/false를 반환하며 보통 if 조건문이나 3항 연산자(ternary operator)와 많이 사용된다.

if (set.has("A")) {
  console.log("A는 세트에 존재합니다."); // A는 세트에 존재합니다.
}

const result = set.has("B") ? "YES" : "NO"; // NO

 

값의 개수 확인

세트의 size 속성을 통해서 해당 세트의 길이, 즉 얼마나 많은 값이 저장되어 있는지를 알아낼 수 있다.

console.log(set.size); // 2

 

모든 값 제거

Set 객체의 모든 값을 제거하려면 clear() 메서드를 사용합한다.

set.clear(); // Set(0) {size: 0}

 

 

Set은 이터러블이다.

Set 객체는 인덱스로 요소에 접근이 불가능하여 iterable하지 않다고 착각할 수 있다.

Set이 맨 위 표에 말한듯이 순서에 의미가 없다고는 하지만 iterable하며, 순회했을 시 생성 순서를 따르긴 한다.

그러므로 전개했을 때 '전개할 때마다 순서가 뒤죽박죽이면 어쩌나' 걱정할 필요는 없다.

 

또한 for ... of 문으로 순회할 수 있으며, 스프레드 문법과 배열 디스트럭처링의 대상이 될 수 있다.

 

 

const set = new Set([1,2,3]);

// Set 객체는 Set.prototype의 Symbol.iterator 메서드를 상속받는 이터레이터이다.
console.log(Symbol.iterabor in set); // true

// for of 사용 가능
for (const value of set) {
	console.log(value);
}

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

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

 

 

Set <-> 배열 변환

실제로 코딩을 하다보면 기존에 존재하는 배열로 부터 새로운 세트를 만들어야 하는 경우가 빈번하다.

이럴 때 다음과 같은 식으로 사용 가능하다.

// 배열 => Set 변환
// new Set(arr) 식으로 배열을 생성자 함수에 전달하는 식이다.
const array = [1, 2, 2, 3, 3, 3];
const set = new Set(array); // Set(3) {1, 2, 3}

// Set => 배열 변환
// Set을 빈 배열 안에 전개하여 배열을 생성할 수 있다.
const arr = [ 1, 2, ...Set ]

 

중복제거를 위해 편하게 쓸 수 있는 트릭

사실 간간히 사용하던 이 활용법을 남겨두려고 이 글을 쓰게 됐다. 어떤 배열에서 중복을 제거하고 싶을 때 Set으로 중복 제거 후 다시 배열 안으로 전개하는 방식으로 가독성도 뛰어나고 효율적인 중복 제거를 할 수 있다. 이때 중복되는 인자가 있다면 맨 나중에 등장한 인자로 overwrite되어 남게 된다. (코테에서는 간간히 써봤고, 실제 프로젝트 시에는 한 번 써봤던거 같다.)

 

// 중복제거
const numbers = [1, 2, 2, 3, 4, 4, 5];
const uniqueNumbers = [...new Set(numbers)];
console.log(uniqueNumbers); // [1, 2, 3, 4, 5]