[JS] Set

doodoo·2023년 2월 21일
0
post-thumbnail

Set

  • Set 객체는 중복되지 않는 유일한 값들의 집합
  • 수학적 집합을 구현하기 위한 자료구조
  • 배열과 유사하지만 몇가지 차이점이 있다.

👉 차이점

구분배열Set 객체
동일한 값 중복 여부OX
요소 순서OX
인덱스로 요소에 접근OX

Set 객체 생성

Set 객체는 Set 생성자 함수로 생성한다. 인수를 전달하지 않으면 빈 Set 객체가 생성된다.

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

이터러블을 인수로 받아 Set 객체를 생성하는데, 이때 중복된 값은 저장되지 않는다.

const set1 = new Set([1, 2, 2, 2, 3]); // Set(3) { 1, 2, 3 }
const set2 = new Set("helllllooo"); // Set(4) { 'h', 'e', 'l', 'o' }

요소 개수 확인

Set.prototype.size 프로퍼티로 Set 객체의 요소 개수를 확인할 수 있다.

const set1 = new Set([1, 2, 2, 3]);
console.log(set1.size); // 3

const { size } = new Set("hello");
console.log(size); // 4

size 프로퍼티는 getter 함수만 존재하는 접근자 프로퍼티
따라서, 값을 할당하여 요소의 개수를 변경할 수 없다.

const set = new Set([1, 2, 2, 3]);
console.log(set.size); // 3

set.size = 10; // 무시된다.
console.log(set.size); // 3

요소 추가

Set.prototype.add 메서드로 요소를 추가할 수 있다.

const set = new Set();
console.log(set); // Set(0) {}

set.add(1);
console.log(set); // Set(1) { 1 }

add 메서드는 새로운 요소가 추가된 Set 객체를 반환한다. 👉 연속 호출 가능

const set = new Set();
console.log(set); // Set(0) {}

set.add(1).add(2).add(3);
console.log(set); //Set(3) { 1, 2, 3 }

set.add(3); // 중복된 요소는 무시됨
console.log(set); // Set(3) { 1, 2, 3 }

일치 비교 연산자 ===를 사용하면 NaN과 NaN을 다르다고 평가한다.
하지만 Set 객체는 NaN과 NaN을 같다고 평가하여 중복 추가를 하지 않는다.

const set = new Set();
console.log(set); // Set(0) {}

console.log(NaN === NaN); // false

set.add(NaN).add(NaN);
console.log(set); // Set(1) { NaN }

일치 비교 연산자 ===는 0과 -0을 같다고 평가한다.
Set 객체도 마찬가지로 같다고 평가하여 중복 추가를 허용하지 않는다.

const set = new Set();
console.log(set); // Set(0) {}

console.log(0 === -0); // true

set.add(0).add(-0);
console.log(set); // Set(1) { 0 }

Set 객체는 모든 값을 요소로 저장할 수 있다.

const set = new Set();
console.log(set); // Set(0) {}

const s = Symbol("symbol!");

set
  .add(1)
  .add("str")
  .add(true)
  .add(undefined)
  .add(null)
  .add([])
  .add({})
  .add(() => {})
  .add(s);

console.log(set);
// Set(8) { 1, 'str', true, undefined, null, [], {}, [Function (anonymous)], Symbol(symbol!) }

요소의 존재 여부 확인

Set.prototype.has 메서드로 Set 객체에 특정 요소가 존재하는지 확인할 수 있다.
존재 여부를 나타내는 불리언 값을 반환한다.

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

console.log(set.has(2)); // true
console.log(set.has(5)); // false

요소 삭제

Set.prototype.delete 메서드로 특정 요소를 삭제할 수 있다.
삭제 성공 여부를 나타내는 불리언 값을 반환한다.

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

set.delete(2); // 인덱스가 아닌 삭제하려는 요소를 전달해야 한다. 
console.log(set); // Set(2) { 1, 3 }

존재하지 않는 요소를 삭제하려 하면 에러 없이 무시된다.

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

set.delete(4); // 무시된다.
console.log(set); // Set(3) { 1, 2, 3 }

요소 일괄 삭제

Set.prototype.clear 메서드를 사용하면 모든 요소를 일괄 삭제할 수 있다.
항상 undefined를 반환한다.

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

console.log(set); // Set(3) { 1, 2, 3 }

set.clear(); // 일괄 삭제

console.log(set); // Set(0) {}

요소 순회

forEach

Set.prototype.forEach 메서드를 사용하면 Set 객체의 요소를 순회할 수 있다.

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

set.forEach((value1, value2, set) => console.log(value1, value2, set));

/*
1 1 Set(3) { 1, 2, 3 }
2 2 Set(3) { 1, 2, 3 }
3 3 Set(3) { 1, 2, 3 }
*/

forEach 메서드에는 콜백 함수를 전달할 수 있고, 콜백 함수는 3개의 인수를 전달받는다.

  • 첫번째: 현재 순회중인 요소 값
  • 두번째: 현재 순회중인 요소 값
  • 세번째: 현재 순회중텍스트인 Set 객체 자체
    👉 첫번째와 두번째 인수가 같은 값인 이유는 ArrayMap에서 사용하는 forEach와 동일한 형태를 유지하기 위해서

for...of

for...of 문으로 순회할 수 있다.
또한 Set 객체는 순서에 의미가 없기 때문에 배열처럼 인덱스를 갖지 않는다.

// for...of 문으로 순회할 수 있다. 
const set = new Set([1, 2, 3]);

for (const value of set) {
  console.log(value); // 1 2 3
}

스프레드 문법, 배열 디스트럭처링

스프레드 문법과 배열 디스트럭처링도 사용할 수 있다.

// 스프레드 문법 사용 가능 
const set = new Set([1, 2, 3]);

console.log([...set]); // [ 1, 2, 3 ]
// 배열 디스트럭처링 할당 가능 
const set = new Set([1, 2, 3]);
const [a, ...rest] = set;

console.log(a); // 1
console.log(rest); // [2, 3]

keys, values, entries

Set.prototype.keysvalues와 동일한 작업을 한다. (Map과 호환성을 위해 만들어짐)

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

const key = set.keys();
console.log(key); // [Set Iterator] { 1, 2, 3 }

Set.prototype.values 는 Set 객체에 요소가 삽입된 순서대로 각 요소의 값을 순환할 수 있는 새로운 이터러블 객체를 반환한다.

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

const value = set.values();

console.log(value); // [Set Iterator] { 1, 2, 3 }
console.log(value.next()); // { value: 1, done: false }
console.log(value.next()); // { value: 2, done: false }
console.log(value.next()); // { value: 3, done: false }
console.log(value.next()); // { value: undefined, done: true }

Set.prototype.entries 는 Set 객체의 각각의 요소를 삽입 순서대로 [value, value] 형태로 만들어 이 배열을 포함하는 새로운 이터러블 객체를 반환한다. (Map과 호환성을 위해 만들어짐)

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

const entries = set.entries();

console.log(entries); // [Set Entries] { [ 1, 1 ], [ 2, 2 ], [ 3, 3 ] }
console.log(entries.next()); // { value: [ 1, 1 ], done: false }
console.log(entries.next()); // { value: [ 2, 2 ], done: false }
console.log(entries.next()); // { value: [ 3, 3 ], done: false }
console.log(entries.next()); // { value: undefined, done: true }
  • Set 객체에는 key가 없다. Map 객체와 비슷한 형태를 유지하기 위해 각각의 요소는 키와 값 자리에 같은 값을 가지게 된다.
  • 결과적으로 [value, value] 형태의 배열이 반환된다.

✅ 요약

  • new Set(iterable) Set 객체 만들기. 이터러블 객체를 전달받으면 그 안의 값을 복사해 Set에 넣는다.
  • size 요소 개수 확인
  • add(value) 값 추가하기
  • has(value) 존재 여부 확인. 있으면 true, 없으면 false
  • delete(value) 값 제거하기. 성공하면 true, 실패하면 false 반환
  • clear() 모든 요소 제거
  • forEachfor...of로 순회 가능
  • 스프레드 문법, 배열 디스트럭처링 가능
  • keys, values 각 요소를 순환할 수 있는 새로운 이터러블 객체 만들기
  • entries [value, value] 형태의 배열이 있는 새로운 이터러블 객체 만들기

📌 참고

0개의 댓글