1. ホーム
  2. javascript

[解決済み] JavaScriptでセットを作成する方法は?

2023-03-12 09:33:59

質問

Eloquent JavaScriptの第4章では、オブジェクトを作成して値のセットを作成し、プロパティ名として値を格納し、プロパティ値として任意の値(例えばtrue)を代入しています。値がすでにセットに含まれているかどうかを確認するために in 演算子が使われます。

var set = {};

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

これはJavaScriptの慣用句なのでしょうか?配列の方が良いのでは?

var set = [];

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

どのように解決するのですか?

設定 がES2015(別名:ES6、すなわちECMAScript 6)で利用できるようになりました。ES6は2015年6月からJavaScriptの現行標準となっています。

ECMAScript 6は、任意の値に対して動作するデータ構造Setを備えています。 があり、高速で、NaNを正しく扱えます。- Axel Rauschmayer , ES6 を探る

最初の2つの例は Axel Rauschmayer の 書籍 ES6 を探求する :

<ブロッククオート

単一の要素を管理する。

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

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

<ブロッククオート

Setのサイズを決定し、それをクリアする。

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

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

私なら ES6を探求する をご覧ください。この本はオンラインで無料で読めますが、もし著者を支援したいのであれば アクセル・ラウシュマイヤー博士 を支援したい場合は、この本を約30ドルで購入することができます。

もし今、SetsとES6を使いたいのなら バベル という ES6 から ES5 へのトランスパイラ、およびそのポリフィルを使用します。

編集:2017年6月6日現在、主要なブラウザのほとんどが最新バージョンでSetを完全にサポートしています(IE 11を除く)。つまり、古いブラウザのサポートにこだわらないのであれば、babelは必要ないかもしれません。現在使用しているブラウザを含め、異なるブラウザでの互換性を確認したい場合は、以下を参照してください。 KangaxのES6互換性テーブル .

EDITです。

初期化についての説明です。セットはそのコンストラクタで任意の同期反復子を取ることができます。つまり、配列だけでなく、文字列やイテレータも取ることができます。例えば、次のような配列と文字列のセットの初期化を考えてみましょう。

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 の拡散構文 . 配列と文字列は同じ要素を持ち、要素の並び順も同じなので、セットも同じように作成されるようです。セットに関するもうひとつの注意点は、セットに対して反復処理を行う場合、要素がセットに挿入された順序に従って反復処理が行われることです。以下は、セットに対する反復処理の例です。

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

セットを初期化するために任意のイテレータを使うことができるので ジェネレータ関数 . 以下は、同じ出力を生成するイテレータの初期化の2つの例です。

// 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博士の本の章を読まずにセットについてもっと知りたいなら、以下のサイトをチェックしてみてください。 MDN docs on Set . MDN には、セットに対する反復処理の例もあります。 forEach を使用し .keys , .values そして .entries といったメソッドがあります。MDN には、集合和集合、集合交点、集合差分、対称集合差分、集合超集合チェックなどの例もあります。願わくば、これらの操作のほとんどが、それらをサポートする独自の関数を構築することなく、JavaScriptで利用できるようになればと思います。実際 新しい Set メソッドに関するこの TC39 の提案 があり、この提案がステージ 4 に到達すれば、将来のある時点で JavaScript の Set に以下のメソッドが追加されることが期待されます。

<ブロッククオート
  • Set.prototype.intersection(iterable) - メソッドは、セットの交差操作によって新しいセットのインスタンスを作成します。
  • Set.prototype.union(iterable) - メソッドは、セットのユニオン操作によって新しいセットのインスタンスを作成します。
  • Set.prototype.difference(iterable) - メソッドは、イテラブルに存在する要素なしで新しいセットを作成します。
  • Set.prototype.symmetricDifference(iterable) - thisまたはiterableのどちらかにのみ存在する要素のSetを返します。
  • Set.prototype.isSubsetOf(イテラブル)
  • Set.prototype.isDisjointFrom(iterable)である。
  • Set.prototype.isSupersetOf(イテラブル)