JavaScript에서 세트를 만드는 방법은 무엇입니까?


82

Eloquent JavaScript, Chapter 4에서는 객체를 생성하고 값을 속성 이름으로 저장하고 임의의 값 (예 : true)을 속성 값으로 할당하여 값 집합을 만듭니다. 값이 이미 세트에 포함되어 있는지 확인하기 위해 in연산자가 사용됩니다.

var set = {};

if (!'Tom' in set) { 
  set.Tom = true;
}

이것은 관용적 JavaScript입니까? 어레이를 더 잘 사용하지 않을까요?

var set = [];

if (!'Tom' in set) { 
  set.push = 'Tom';
}

1
'Tom' in set진실한 배열이 어떻게 보일 것으로 기대 하십니까? 그것은 당신이 뭔가 에 대해 잘못된 가정을 가지고있는 것 같습니다 . 그리고 나는 무엇에 대해 알아 내려고 노력 하고 있습니다.

10
참고로 괄호가 필요 if(!('Tom' in set))합니다.. 현재는 것을 의미 false in set하기 때문에 !'Tom' === false.
pimvdb 2011

ES6이 세트를 가지고, 아래의 존의 답변을 참조
벤 Taliadoros

답변:


101

세트 는 이제 ES2015 (일명 ES6, 즉 ECMAScript 6)에서 사용할 수 있습니다. ES6는 2015 년 6 월부터 JavaScript의 현재 표준이었습니다.

ECMAScript 6에는 임의의 값에 대해 작동하는 데이터 구조 세트가 있으며, 빠르며 NaN을 올바르게 처리합니다. - 악셀 Rauschmayer , 탐색 ES6

Axel Rauschmayer의 저서 Exploring ES6 에서 처음 두 가지 예 :

단일 요소 관리 :

> let set = new Set();
> set.add('red')

> set.has('red')
true
> set.delete('red')
true
> set.has('red')
false

세트의 크기 결정 및 지우기 :

> let set = new Set();
> set.add('red')
> set.add('green')

> set.size
2
> set.clear();
> set.size
0

JavaScript의 세트에 대해 자세히 알아 보려면 Exploring ES6를 확인하십시오 . 이 책은 온라인에서 무료로 읽을 수 있지만 저자 Axel Rauschmayer 박사 를 지원하고 싶다면 약 $ 30에 책을 구입할 수 있습니다.

이제 세트와 ES6을 사용하려면 Babel , ES6에서 ES5 로의 트랜스 파일러 및 해당 폴리 필을 사용할 수 있습니다 .

편집 : 2017 년 6 월 6 일 현재 대부분의 주요 브라우저는 최신 버전 (IE 11 제외)에서 전체 세트를 지원합니다. 즉, 이전 브라우저를 지원하지 않는 경우 바벨이 필요하지 않을 수 있습니다. 현재 브라우저를 포함하여 다른 브라우저에서 호환성을 확인하려면 Kangax의 ES6 호환성 표를 확인하십시오 .

편집하다:

초기화에 대한 설명입니다. 집합은 생성자에서 모든 동기 반복 가능 항목을 사용할 수 있습니다. 즉, 배열뿐만 아니라 문자열 및 반복자를 사용할 수 있습니다. 예를 들어 세트의 다음 배열 및 문자열 초기화를 사용하십시오.

const set1 = new Set(['a','a','b','b','c','c']);
console.log(...set1);
console.log(set1.size);
const set2 = new Set("aabbcc");
console.log(...set2);
console.log(set2.size);

배열과 문자열의 두 출력이 동일합니다. 참고 ...set1는 IS 확산 구문 . iterable의 각 요소가 세트에 하나씩 추가되는 것처럼 보이므로 배열과 문자열 모두 동일한 요소를 가지며 요소가 동일한 순서이기 때문에 세트가 동일하게 생성됩니다. 집합에 대해주의해야 할 또 다른 점은 집합을 반복 할 때 요소가 집합에 삽입 된 순서를 따른다는 것입니다. 다음은 세트를 반복하는 예입니다.

const set1 = new Set(['a','a','b','b','c','c']);
for(const element of set1) {
  console.log(element);
}

이터 러블을 사용하여 집합을 초기화 할 수 있으므로 생성기 함수 에서 이터레이터를 사용할 수도 있습니다 . 다음은 동일한 출력을 생성하는 반복기 초기화의 두 가지 예입니다.

// a simple generator example
function* getLetters1 () {
  yield 'a';
  yield 'a';
  yield 'b';
  yield 'b';
  yield 'c';
  yield 'c';
}

// a somewhat more commonplace generator example
// with the same output as getLetters1.
function* getLetters2 (letters, repeatTimes) {
  for(const letter of letters) {
    for(let i = 0; i < repeatTimes; ++i) { 
      yield letter;
    }
  }
}

console.log("------ getLetters1 ------");
console.log(...getLetters1());
const set3 = new Set(getLetters1());
console.log(...set3);
console.log(set3.size);

console.log("------ getLetters2 ------");
console.log(...getLetters2('abc', 2));
const set4 = new Set(getLetters2('abc', 2));
console.log(...set4);
console.log(set4.size);

이 예제의 생성기 함수는 반복되지 않도록 작성 될 수 있지만 생성기 함수가 더 복잡하고 다음이 성능에 너무 부정적인 영향을 미치지 않는 한 Set 메서드를 사용하여 다음과 같은 생성기에서 값만 가져올 수 있습니다. 반복하지 마십시오.

Rauschmayer 박사의 책을 읽지 않고 세트에 대해 더 많이 알고 싶다면 Set 에서 MDN 문서를 확인할 수 있습니다 . MDN 또한 사용하는 등 일련의 반복보다 예 보유 forEach및 이용 .keys, .values.entries방법. MDN에는 또한 집합 집합, 교차 집합, 집합 차이, 대칭 집합 차이 및 집합 수퍼 집합 검사와 같은 예가 있습니다. 바라건대 이러한 작업의 대부분은이를 지원하는 자체 함수를 빌드 할 필요없이 JavaScript에서 사용할 수 있습니다. 사실, 제안이 4 단계에 도달 할 경우 향후 어느 시점에서 JavaScript의 Set에 다음 메서드를 추가해야하는 새로운 Set 메서드에 대한이 TC39 제안이 있습니다.

  • Set.prototype.intersection (iterable)-set 교차 연산으로 새로운 Set 인스턴스를 생성합니다.
  • Set.prototype.union (iterable)-set union 연산으로 새로운 Set 인스턴스를 생성합니다.
  • Set.prototype.difference (iterable)-메서드는 iterable에 요소없이 새 Set을 만듭니다.
  • Set.prototype.symmetricDifference (iterable)-this 또는 iterable에서만 찾은 요소 집합을 반환합니다.
  • Set.prototype.isSubsetOf (반복 가능)
  • Set.prototype.isDisjointFrom (반복 가능)
  • Set.prototype.isSupersetOf (반복 가능)

또한 Set 자체는 반복 가능하므로 다른 집합으로 집합을 초기화하여 복사본을 만들거나 합집합 작업을 위해 new Set ([... setA, ... setB])와 같은 작업을 수행 할 수 있습니다.
John

1
@LanceKind 배열뿐만 아니라 반복 가능한 모든 집합을 초기화 할 수 있음을 보여주는 것을 포함하여 몇 가지 추가 정보를 추가했습니다.
John

32

dict 객체를 세트로 사용합니다. 이것은 문자열과 숫자와 함께 작동하지만 사용자 지정 같음 및 비교 연산자를 사용하는 개체 집합을 원하면 문제가 발생한다고 생각합니다.

세트 만들기 :

var example_set = 
{
    'a':true,
    'b':true,
    'c':true
}

세트에 포함되는지 테스트

if( example_set['a'] ){
    alert('"a" is in set');
}

세트에 요소 추가

example_set['d'] = true;

세트에서 요소 제거

delete example_set['a'];


1
내가 작업중인 코드는 .NET을 지원하지 않는 이전 버전의 엔진을 사용하고있었습니다 Set. 이것은 도움이되었습니다.
Abhijith Madhav

16

집합은 중복 항목을 허용하지 않으며 일반적으로 미리 정의 된 순서를 보장하지 않습니다. 배열은이 두 가지를 모두 수행하므로 집합이라는 의미를 위반합니다 (추가 확인을 수행하지 않는 한).


2
배열은 예를 들어 arr.push에 대한 ... 중복 된 항목을 필터링하지 않습니다 ({ID : 1, 이름 : "제이크"})과 같은 목표 - C에서 NSSet과 같은 :
iTux

당신이 그것을 mot-a-mot 받아들이면, 아닙니다. 그러나 id를 배열 (맵) 키로 사용할 수 있습니다. arr[id] = {"name": "Jake"};
Buffalo

11

첫 번째 방법은 관용적 인 JavaScript입니다.

키 / 값 쌍을 저장하려면 항상 JavaScript 객체를 사용해야합니다. 어레이의 경우 몇 가지 문제가 있습니다.

  1. 인덱스는 숫자 값입니다.

  2. 반복하지 않고 값이 배열에 있는지 확인하는 쉬운 방법이 없습니다.

  3. 세트는 중복을 허용하지 않습니다. 배열이 그렇습니다.


속성 값에 할당하는 것이 가장 좋은 것은 무엇입니까?
helpermethod dec. 2011

1
JavaScript 배열에서 중복 요소를 제거 할 수 있습니다. stackoverflow.com/a/12166248/975097
Anderson Green

9

배열에서 집합을 만들려면 다음을 수행하십시오.

let arr = [1, 1, 2, 1, 3];
let mySet = new Set(arr); // Set { 1, 2, 3 }

이것은 내가 파이썬으로 프로그래밍 할 때 아주 좋아했던 설탕 구문입니다. ES6가 마침내 같은 일을 할 수있게해서 기뻤습니다.

참고 : 내가 말한 내용이 귀하의 질문에 직접 답변하지 않았다는 것을 알고 있습니다. ES5에서이 "해킹"이있는 이유는 키에 의한 객체 조회 시간이 배열 (O (n))보다 훨씬 빠르기 때문입니다 (O (1)). 성능이 중요한 응용 프로그램에서는 성능 향상을 위해이 정도의 가독성이나 직관을 희생 할 수 있습니다.

하지만 2017 년에 오신 것을 환영 합니다. 이제 모든 주요 최신 브라우저에서 적절한 Set 를 사용할 수 있습니다 !


6

세트 ES6/ ES2015:

ES6/ ES2015이제 세트가 내장되어 있습니다. 집합은 원시 값이든 객체 참조이든 모든 유형의 고유 한 값을 저장할 수있는 데이터 구조입니다. ES6다음과 같은 방식으로 내장 된 집합 생성자를 사용하여 집합을 선언 할 수 있습니다 .

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

Set 생성자를 사용하여 집합을 만들 때 새로 만든 집합 개체는 Set.prototype. 여기에는 모든 종류의 보조 방법과 속성이 있습니다. 이렇게하면 다음 작업을 쉽게 수행 할 수 있습니다.

예:

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

// checkout the size of the set
console.log('size is: ' + set.size);

// has method returns a boolean, true if the item is in the set
console.log(set.has(1));

// add a number
set.add(6);

// delete a number
set.delete(1);

// iterate over each element using a callback
set.forEach((el) => {
  console.log(el);
});

// remove all the entries from the set
set.clear();

브라우저 호환성 :

이제 일부 기능이 누락 된 IE를 제외한 모든 주요 브라우저가 세트를 완벽하게 지원합니다. 정확한 참조는 mdn 문서 를 참조하십시오 .


@Velojet : 알겠습니다.
kjhughes

3

베어 자바 스크립트 객체를 사용하여 집합을 에뮬레이트하는 데는 두 가지 문제가 있습니다. 첫째, 객체는 "in"연산자를 망칠 수있는 상속 된 속성을 가질 수 있고 둘째,이 방식으로 스칼라 값만 저장할 수 있습니다. 객체 집합을 만드는 것은 그렇지 않습니다. 가능한. 따라서, 세트의 실제 구현 방법을 제공해야 add하고 contains대신에 일반의 in재산 할당.


@kojiro : 키로서 사용되는 경우 객체는 문자열로 변환 :set={};set[{x:1}]=123;alert(set[{z:99}])
게오르그

3

당신은 시도 할 수 양동이를 , 자바 스크립트 데이터 구조 라이브러리이며 세트를 조작하는 데 필요한 모든 기능이 들어 있습니다.


addAll (array) 메소드를 제공합니까?
jorrebor 2013

1

Set 객체 🔷의 기본 생성 및 사용

let mySet = new Set()

mySet.add(2)         // Set {2}
mySet.add(7)         // Set {2, 7}
mySet.add(7)         // Set {2, 7}
mySet.add('my text') // Set {2, 7, 'my text'}
let myObj = { a: 1, b: 2 }
mySet.add(myObj)     // Set {2, 7, 'my text', {...}}
mySet.has(2)         // true
mySet.has(myObj)     // true
mySet.size           // 4

되풀이

for (let item of mySet) console.log(item)  // 2, 7, 'my text', {a:1, b:2}
mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}

배열로 변환

var myArr = Array.from(mySet)             // [2, 7, 'my text', {a:1, b:2}]

❕ 세트가 제공하는 가장 뚜렷한 기능은 세트 객체의 모든 값이 고유해야한다는 것입니다. 따라서 중복 값을 추가 할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.