web-dev-qa-db-ja.com

JavaScriptでセットを作成する方法は?

Eloquent JavaScriptの第4章では、オブジェクトを作成して値をプロパティ名として保存し、任意の値(例:true)をプロパティ値として割り当てることにより、値のセットが作成されます。値がすでにセットに含まれているかどうかを確認するには、in演算子を使用します。

var set = {};

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

これは慣用的なJavaScriptですか?配列をさらに使いこなすのではないでしょうか?

var set = [];

if (!'Tom' in set) { 
  set.Push = 'Tom';
}
72
helpermethod

セット は、ES2015(別名ES6、つまりECMAScript 6)で利用可能になりました。 ES6は、2015年6月以来JavaScriptの現在の標準となっています。

ECMAScript 6には、任意の値に対して機能し、高速でNaNを正しく処理するデータ構造セットがあります。 - Axel RauschmayerES6の探索

Axel Rauschmayer's book Exploring ES6 の最初の2つの例:

単一要素の管理:

> 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 をご覧ください。この本は無料でオンラインで読むことができますが、著者をサポートしたい場合は Dr。Axel Rauschmayer 約30ドルで購入できます。

セットとES6を使用する場合は、 Babel 、ES6からES5へのトランスパイラー、およびそのポリフィルを使用できます。

編集:2017年6月6日の時点で、ほとんどの主要なブラウザーは最新バージョンで完全なセットサポートを備えています(IE 11)を除く。現在のブラウザを含むさまざまなブラウザで互換性を確認したい場合は、 KangaxのES6互換性テーブル を確認してください。

84
John

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'];

32
Chris Dutrow

セットは重複エントリを許可せず、通常、事前定義された順序を保証しません。配列はこれらの両方を行うため、セットであることの意味に違反します(追加のチェックを行わない限り)。

15
Jon Newmuis

最初の方法は、慣用的なJavaScriptです。

キーと値のペアを保存する場合は、JavaScriptオブジェクトを使用する必要があります。配列に関しては、いくつかの問題があります。

  1. インデックスは数値です。

  2. ループスルーせずに値が配列内にあるかどうかを確認する簡単な方法はありません。

  3. セットは重複を許可しません。配列はそうします。

11
Justin Niessner

配列からセットを作成する場合は、次のようにします。

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

これは、Pythonでプログラミングするときに空想した砂糖の構文なので、ES6がようやく同じことを実行できるようになったことを嬉しく思います。

注:その後、私はあなたの質問に直接答えなかったと言ったことに気付きます。 ES5でこの「ハック」を行う理由は、キーによるオブジェクトのルックアップ時間が配列(O(n))よりもはるかに速い(O(1))ためです。パフォーマンスが重要なアプリケーションでは、パフォーマンスを向上させるために、この読みやすさや直感を少し犠牲にすることができます。

しかし、2017年にようこそ。ここでは、現在の主要なすべてのブラウザーで適切なSetを使用できます。

8
benjaminz

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 docs

6

Buckets を試すことができます。これはJavaScriptデータ構造ライブラリであり、セットを操作するために必要なものがすべて揃っています。

3
Daniel

ベアjavascriptオブジェクトを使用してセットをエミュレートすることには2つの問題があります。1つ目は、オブジェクトに「in」演算子を台無しにする継承プロパティがあり、2つ目は、この方法でスカラー値のみを保存でき、オブジェクトのセットが可能。したがって、Setsの現実的な実装では、単純なaddおよびプロパティの割り当ての代わりに、メソッドcontainsおよびinを提供する必要があります。

3
georg