Set 자료형
- 교유한 값의 모음
- 각각의 값은
Set
안에서 한번만 나타날 수 있다.
- 모든 데이터 유형의 값을 받을 수 있다.
Set Methods
Method | Description |
---|
new Set() | Set 을 생성한다. |
add() | Set 에 새로운 원소를 추가한다. |
delete() | Set 에서 원소를 제거한다. |
has() | 만약 원소가 있다면 true 를 반환한다. |
clear() | Set 안의 모든 원소를 제거한다. |
forEach() | 각 요소에 대해 callback 함수를 호출한다. |
values() | Set 의 모든 값을 포함하는 Iterator 를 반환한다. |
keys() | values() 와 동일하다. |
entries() | Set 에서 [value,value] 쌍을 가진 Iterator 를 반환한다. |
Property | Description |
---|
size | Set 의 요소 수를 반환한다. |
Array
객체와의 관계
var myArray = ['value1', 'value2', 'value3'];
var mySet = new Set(myArray);
mySet.has('value1');
console.log([...mySet]);
기본 집합 연산 구현
Set.prototype.isSuperset = function(subset) {
for (var elem of subset) {
if (!this.has(elem)) {
return false;
}
}
return true;
}
Set.prototype.union = function(setB) {
var union = new Set(this);
for (var elem of setB) {
union.add(elem);
}
return union;
}
Set.prototype.intersection = function(setB) {
var intersection = new Set();
for (var elem of setB) {
if (this.has(elem)) {
intersection.add(elem);
}
}
return intersection;
}
Set.prototype.difference = function(setB) {
var difference = new Set(this);
for (var elem of setB) {
difference.delete(elem);
}
return difference;
}
var setA = new Set([1, 2, 3, 4]),
setB = new Set([2, 3]),
setC = new Set([3, 4, 5, 6]);
setA.isSuperset(setB);
setA.union(setC);
setA.intersection(setC);
setA.difference(setC);
Array vs Set
요소를 추가하는 경우
const n = 100000;
const myArr = Array.from(Array(n)).map((v, i) => i);
const mySet = new Set(myArr);
console.time("push array");
myArr.push(n + 1);
console.timeEnd("push array");
console.time("add set");
mySet.add(n + 1);
console.timeEnd("add set");
요소를 제거하는 경우
console.time("indexOf, splice array");
const index = myArr.indexOf(n / 2);
myArr.splice(index, 1);
console.timeEnd("indexOf, splice array");
console.time("delete loop set");
mySet.delete(n / 2);
console.timeEnd("delete loop set");
요소를 탐색하는 경우
console.time("indexOf array");
myArr.indexOf(n / 2);
console.timeEnd("indexOf array");
console.time("has set");
mySet.has(n / 2);
console.timeEnd("has set");
요소를 순회하는 경우
const length = myArr.length
console.time("for loop array");
for (let i = 0; i < length; i++) {
myArr;
}
console.timeEnd("for loop array");
console.time("forEach loop array");
myArr.forEach((v) => {
myArr;
});
console.timeEnd("forEach loop array");
console.time("for of loop array");
for (let i of myArr) {
myArr;
}
console.timeEnd("for of loop array");
console.time("forEach loop set");
mySet.forEach((v) => {
mySet;
});
console.timeEnd("forEach loop set");
console.time("for of loop set");
for (let v of mySet) {
mySet;
}
console.timeEnd("for of loop set");
| N | Array | Set |
---|
요소를 추가하는 경우 (push/add) | 100,000 | 0.563 ms | 0.004 ms |
| 1,000,000 | 2.409 ms | 0.002 ms |
요소를 제거하는 경우 (inexOf , splice / delete) | 100,000 | 0.0349 ms | 0.002 ms |
| 1,000,000 | 0.387 ms | 0.002 ms |
요소를 탐색하는 경우 (indexOf/has) | 100,000 | 0.013 ms | 0.001 ms |
| 1,000,000 | 0.130 ms | 0.001 ms |
요소를 순회하는 경우 (for) | 100,000 | 0.967 ms | |
| 1,000,000 | 1.551 ms | |
요소를 순회하는 경우 (forEach) | 100,000 | 1.05 ms | 0.802 ms |
| 1,000,000 | 6.134 ms | 6.045 ms |
요소를 순회하는 경우 (for ... of) | 100,000 | 2.446 ms | 1.563 ms |
| 1,000,000 | 9.910 ms | 9.925 ms |
결과
- 요소를
추가
, 제거
, 탐색
하는 경우 Set
이 더 빠르며 N
이 커질수록 확연한 차이를 볼 수 있다.
하지만, 이러한 작업을 위해 Array
를 Set
으로 변환하여 작업하는 것은 변환 시간이 오래 걸릴 수 있으므로 주의가 필요하다.
- 요소를
순회
하는 경우 forEach
, for ... of
모두 Set
과 Array
의 차이가 거의 나지 않는 것을 볼 수 있다.
하지만 Array
의 경우 for
을 사용한 순회
가 다른 방법에 비해 훨씬 빠른 성능을 보인다.
따라서 Array
의 경우 성능이 중요한 경우 for
을 사용하여 순회하자.
단, for
을 사용한 순회시 forEach
에 비해 가독성이 떨어질 수 있으므로 주의하자.
참고
Set | MDN
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set
JavaScript Sets
https://www.w3schools.com/js/js_object_sets.asp
Javascript Set vs. Array performance
https://stackoverflow.com/questions/39007637/javascript-set-vs-array-performance
for loop
가 forEach
보다 빠른 이유
https://stackoverflow.com/questions/43821759/why-array-foreach-is-slower-than-for-loop-in-javascript