Set 객체
Set 객체란 중복되지 않는 유일한 값들의 집합이다.
배열과 비슷해 보이지만 다음과 같은 차이점이 존재한다.
- 동일한 값을 중복하여 포함하지 못한다.
- 요소 순서가 의미가 없다.
- 인덱스로 요소에 접근하지 못한다.
Set은 수학적 집합을 구현하기 위한 자료구조로서, Set 객체를 통해 다양한 집합을 구현할 수 있다.
그럼 먼저 Set 객체를 생성하는 법을 알아보자.
Set 객체 생성하기
Set 객체는 Set 생성자 함수로 생성한다. 함수에 인수를 전달하지 않으면 빈 Set 객체가 생성된다.
const set = new Set();
console.log(set); // Set(0) {}
Set 생성자 함수는 이터러블(반복 가능한)을 인수로 받아 객체를 생성한다.
이터러블의 중복된 값은 객체 요소로 저장되지 않는다 => 중복되지 않는다.
const set = new Set([1,2,2,3,3,4]);
console.log(set); // Set(4) {1,2,3,4}
숫자뿐만 아니라 글자가 중복된 것도 저장되지 않는다.
Set 객체의 특성을 이용한 배열 중복요소 제거하기
배열의 중복 요소를 제거하는 방법
const uniq = array => array.filter((v, i, self) => self.indexOf(v) === i);
console.log(uniq([2,2,2,2,1,3,3])); // [2,1,3]
Set을 이용한 배열 중복 요소 제거 방법
const uniq = array => [...new Set(array)];
console.log(uniq([2,2,2,2,1,3,3])); // [2,1,3]
방법은 다르지만 Set 객체의 특성을 이용했을 경우의 방법이 훨씬 간단한 걸 확인할 수 있다.
Set 객체 요소 개수 확인하기
Set.prototype.size 프로터티를 사용하여 개수를 확인할 수 있다.
const { size } = new Set([2,1,3,3,4]);
console.log(size); // 4
const set = new Set([2,1,3,3,4]);
console.log(set.size); // 4
size 프로퍼티는 getter 함수만 존재하는 접근자 프로퍼티이다. 그러므로 size 프로퍼티를 통해서 개수를 변경할 수 없다.
Set 객체 요소 추가하기
Set.prototype.add 메서드를 사용하여 요소를 추가할 수 있다.
const set = new Set();
console.log(set);
set.add(1);
console.log(set); // 1
//add()뒤에 add()메서드 추가 가능
set.add(2).add(3);
console.log(set); // 3
// 하지만 증복된 요소는 추가되지 않는다.
set.add(4).add(4);
console.log(set); // 4
add 메서드는 새로운 요소가 추가된 Set객체를 반환한다. 따라서 add 메서드를 호출한 뒤 add 메서드를 연속적으로 사용할 수 있다.
하지만 중복된 요소는 추가되지 않는다. (에러x, 무시됨)
객체나 배열처럼 자바스크립트의 모든 값을 요소로 저장할 수 있다.
const set = new Set();
set
.add(1)
.add('a')
.add(true)
.add(undefined)
.add(null)
.add({})
.add([])
.add(() => {});
console.log(set);
// Set(8) {1, 'a', true, undefined, null, {}, [], () => {}}
Set 객체 요소 존재 여부 확인하기
객체 내에 특정 요소가 존재하는지 확인하려면 Set.prototype.has 메서드를 사용하면 된다.
요소의 존재 여부를 불리언 값으로 반환한다.
const set = new Set([1, 2, 3, 4]);
console.log(set.has(2)); // true
console.log(set.has(5)); // false
Set 객체 요소 삭제하기
Set.prototype.delete 메서드를 사용하여 객체 내 요소를 삭제할 수 있다.
성공 여부는 불리언 값을 반환한다.
삭제하려는 인덱스가 아니라 요소의 값을 인수로 전달해야 한다. 배열과 달리 인덱스를 갖지 않기 때문이다.
const set = new Set([1,2,3]);
// 요소 3를 삭제한다.
set.delete(3) // true
존재하지 않는 요소를 삭제하려면 에러가 나지 않고 무시된다.
add 메서드와는 다르게 삭제의 성공 여부를 불리언 값으로 반환하기 때문에 연속해서 호출할 수 없다.
Set 객체 요소 모두 삭제하기
객체의 모든 요소를 삭제하려면 Set.prototype.clear 메서드를 사용한다.
clear 메서드는 언제나 undefined를 반환한다.
const set = new Set([1,2,3]);
set.clear(); // undefined
console.log(set); // Set(0) {}
Set 객체 요소 순회하기
Set.prototype.forEach 메서드를 사용한다.
Set 객체의 forEach는 배열의 forEach와 유사하게 콜백 함수와 콜백 함수 내부에서 this로 사용될 객체를 인수로 전달한다.
콜백 함수는 3개의 인수를 전달 받는다.
- 현재 순회 중인 요소값
- 현재 순회 중인 요소값
- 현재 순회 중인 Set 객체 자체
1번째 인수와 2번째 인수는 값은 값이며 배열의 forEach와 인터페이스를 통일하기 위해서이며 다른 이유는 없다.
const set = new Set([1,2,3]);
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 객체는 이터러블이기 때문에 for...of문으로도 순회할 수 있다.
스프레드 문법과 배열 디스트럭처링의 대상이 될 수도 있다.