Set
BaselineWidely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
* Some parts of this feature may have varying levels of support.
Set
オブジェクトは、プリミティブ値やオブジェクト参照を問わず、あらゆる型で多数の一意の値を格納することができます。
解説
Set
オブジェクトは値の集合です。Set
に重複する値は格納出来ません。Set
内の値は集合内で一意になります。Set
はその要素について挿入順で反復処理を行うことができます。挿入順は、各要素がadd
メソッドによって正常にSet
に挿入された順番に対応します。
仕様書ではSet
の実装について「平均アクセス時間が集合内の要素数に対して線形探索以下」であることが要求されています。したがって、計算量が O(N) よりも優れている限り、内部的にはハッシュ表(ルックアップは O(1))、探索木(ルックアップは O(log(N)))、または他のデータ構造として表すことができます。
値の等価性
値の等値性は、SameValueZero アルゴリズムに基づいています。(以前はSameValue を使用しており、0 と -0 は異なるものとして扱われていました。詳しくはブラウザーの互換性の "Key equality for -0 and 0" を参照してください。)つまり、NaN
はNaN
と同じとみなされ(例えNaN !== NaN
であっても)、それ以外の値は===
演算子の挙動に従って等しいとみなされます。
パフォーマンス
has
メソッドは、値がSet
内にあるかどうかをチェックします。これは、以前にSet
に追加された要素のほとんどを確認するよりも平均すると高速なアプローチを使用します。特に、Array
オブジェクトのlength
がSet
オブジェクトのsize
と等しい場合、平均してArray.prototype.includes
メソッドより速くなります。
Set の合成
Set
オブジェクトは、数学演算のように集合を合成するためのいくつかのメソッドを提供します。これらのメソッドには、以下のようなものがあります。
メソッド | 返値の型 | 数学の同等のもの | ベン図 |
---|---|---|---|
A.difference(B) | Set | ||
A.intersection(B) | Set | ||
A.symmetricDifference(B) | Set | ||
A.union(B) | Set | ||
A.isDisjointFrom(B) | 論理型 | ||
A.isSubsetOf(B) | 論理型 | ||
A.isSupersetOf(B) | 論理型 |
より一般化できるように、これらのメソッドは Set オブジェクトだけでなく、Set 風オブジェクトも受け入れます。
Set 風オブジェクト
すべてのSet 合成メソッドでは、this
が実際のSet
インスタンスであることが要求されますが、引数は Set 風であるだけで構いません。Set 風オブジェクトとは、次のことを提供するオブジェクトです。
例えば、Map
オブジェクトは Set 風です。なぜなら、size
、has()
、keys()
を保有しており、Set メソッドで使用する際に、キーの Set のように動作するからです。
const a = new Set([1, 2, 3]);const b = new Map([ [1, "one"], [2, "two"], [4, "four"],]);console.log(a.union(b)); // Set(4) {1, 2, 3, 4}
メモ:Set 風プロトコルは、要素を生成するためにkeys()
メソッドを[Symbol.iterator]()
の代わりに呼び出します。これは、Map を有効な Set 風オブジェクトにするためです。なぜなら、Map の場合、イテレーターは項目を生成しますが、has()
メソッドはキーを取得するからです。
配列は、has()
メソッドやsize
プロパティを持っておらず、keys()
メソッドが要素ではなくインデックスを生成するため、Set 風ではありません。WeakSet
オブジェクトも、keys()
メソッドを持たないため、Set 風ではありません。
Set 風のブラウザー API
ブラウザーのSet
風オブジェクト(または「集合風オブジェクト」)とは、ウェブ API の中で多くの点でSet
のように動作するインターフェイスです。
Set
のように、要素はオブジェクトに追加した順番に反復処理することができます。Set
風オブジェクトとSet
には、名前と動作が同じプロパティとメソッドもあります。しかし Set とは異なり、各アイテムには特定の定義済みの型しか使用できません。
許可されている型には仕様書の IDL 定義に設定されています。例えば、GPUSupportedFeatures
はSet
風オブジェクトですが、キーと値として文字列を使用する必要があります。これは下記の仕様 IDL で定義されています。
interface GPUSupportedFeatures { readonly setlike<DOMString>;};
Set
風オブジェクトは、読み取り専用か読み書き可能かのどちらかです(上記の IDL でreadonly
キーワードを確認してください。
- 読み取り専用の
Set
風オブジェクトにはsize
プロパティがあり、entries()
,forEach()
,has()
,keys()
,values()
,[Symbol.iterator]()
の各メソッドがあります。 - 読み書き可能な
Set
風オブジェクトには、それに加えてclear()
,delete()
,add()
の各メソッドがあります。
メソッドとプロパティはSet
の等価なエンティティと同じ動作をしますが、項目のの型に制限があります。
以下のものが、読み取り専用のSet
風ブラウザーオブジェクトの例です。
以下のものが、読み書き可能なSet
風ブラウザーオブジェクトの例です。
コンストラクター
Set()
新しい
Set
オブジェクトを生成します。
静的プロパティ
Set[Symbol.species]
派生オブジェクトを生成するために使用されるコンストラクター関数です。
インスタンスプロパティ
これらのプロパティはSet.prototype
で定義されており、すべてのSet
インスタンスから共有されます。
Set.prototype.constructor
このインスタンスオブジェクトを生成したコンストラクター関数です。
Set
インスタンスの場合、初期値はSet
コンストラクターです。Set.prototype.size
Set
オブジェクト内の値の数を返します。Set.prototype[Symbol.toStringTag]
[Symbol.toStringTag]
プロパティの初期値は文字列の"Set"
です。 このプロパティはObject.prototype.toString()
で利用されます。
インスタンスメソッド
Set.prototype.add()
この
Set
オブジェクト内に同じ値を持つ要素がまだ存在しなかった場合、指定した値を持つ新しい要素をSet
オブジェクトに挿入します。Set.prototype.clear()
この
Set
オブジェクトからすべての要素を取り除きます。Set.prototype.delete()
value
に関連した要素を取り除き、要素の削除に成功したかどうかを示す論理値を返します。Set.prototype.has(value)
はその後はfalse
を返します。Set.prototype.difference()
集合を取り、この
Set
の中にあって与えられた集合の中にない要素が入った新しいSet
を返します。Set.prototype.entries()
Set
オブジェクト内の各要素を[value, value]
の配列の形で挿入順で返す、新しいイテレーターオブジェクトを返します。これはMap
オブジェクトと似ていますが、それぞれの項目のkey がSet
ではvalue と同じになります。Set.prototype.forEach()
この
Set
オブジェクト内に存在する各値に対して、挿入順に一度ずつcallbackFn
を呼びます。thisArg
引数が指定された場合、それぞれのcallbackFn
の呼び出しにおいてthis
の値として使用されます。Set.prototype.has()
この
Set
オブジェクト内に引数で与えられた値をもつ要素が存在するかどうかを示す論理値を返します。Set.prototype.intersection()
集合を取り、この
Set
の中と与えられた集合の中の両方にある要素が入った新しいSet
を返します。Set.prototype.isDisjointFrom()
集合を取り、この
Set
の中に与えられた集合の中の要素がないかどうかを示す論理値を返します。Set.prototype.isSubsetOf()
集合を取り、この
Set
の中のすべての要素が与えられた集合の中に存在するかどうかを示す論理値を返します。Set.prototype.isSupersetOf()
集合を取り、与えられた集合の中のすべての要素がこの
Set
に存在するかどうかを示す論理値を返します。Set.prototype.keys()
Set.prototype.values()
の別名です。Set.prototype.symmetricDifference()
集合を取り、この
Set
または与えられた集合の中に存在するものの、両方には存在しない要素が入った新しいSet
を返します。Set.prototype.union()
集合を取り、この
Set
または与えられた集合の中のどちらか、または両方に存在する要素が入った新しいSet
を返します。Set.prototype.values()
Set
オブジェクト内の各要素の値を挿入順に返す、新しいイテレーターオブジェクトを返します。Set.prototype[Symbol.iterator]()
Set
オブジェクト内の各要素の値を挿入順に返す、新しいイテレーターオブジェクトを返します。
例
Set オブジェクトの使用
const mySet1 = new Set();mySet1.add(1); // Set(1) { 1 }mySet1.add(5); // Set(2) { 1, 5 }mySet1.add(5); // Set(2) { 1, 5 }mySet1.add("some text"); // Set(3) { 1, 5, 'some text' }const o = { a: 1, b: 2 };mySet1.add(o);mySet1.add({ a: 1, b: 2 }); // o は別なオブジェクトを参照しているので、これは良いmySet1.has(1); // truemySet1.has(3); // false。 3 はセットに追加されないためmySet1.has(5); // truemySet1.has(Math.sqrt(25)); // truemySet1.has("Some Text".toLowerCase()); // truemySet1.has(o); // truemySet1.size; // 5mySet1.delete(5); // セットから 5 を取り除くmySet1.has(5); // false。 5 は削除されたmySet1.size; // 4。 1 つの値を削除したばかりであるためmySet1.add(5); // Set(5) { 1, 'some text', {...}, {...}, 5 }。 一度削除された要素は、新しい要素として追加されるため削除前の位置は保持されないconsole.log(mySet1); // Set(5) { 1, "some text", {…}, {…}, 5 }
Set の反復処理
挿入順に要素を訪問する集合に対する反復処理です。
for (const item of mySet1) { console.log(item);}// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5for (const item of mySet1.keys()) { console.log(item);}// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5for (const item of mySet1.values()) { console.log(item);}// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5// ここではキーと値は同じfor (const [key, value] of mySet1.entries()) { console.log(key);}// 1, "some text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5// Set オブジェクトを Array オブジェクトに Array.from で変換const myArr = Array.from(mySet1); // [1, "some text", {"a": 1, "b": 2}, {"a": 1, "b": 2}, 5]// HTML 文書内であれば以下のものも動作するmySet1.add(document.body);mySet1.has(document.querySelector("body")); // true// Set と Array の間の変換const mySet2 = new Set([1, 2, 3, 4]);console.log(mySet2.size); // 4console.log([...mySet2]); // [1, 2, 3, 4]// 交差する様子をシミュレートすることができるconst intersection = new Set([...mySet1].filter((x) => mySet2.has(x)));// 差をシミュレートすることができるconst difference = new Set([...mySet1].filter((x) => !mySet2.has(x)));// セット内の項目を forEach() で反復処理mySet2.forEach((value) => { console.log(value);});// 1// 2// 3// 4
基本的な集合演算の実装
function isSuperset(set, subset) { for (const elem of subset) { if (!set.has(elem)) { return false; } } return true;}function union(setA, setB) { const _union = new Set(setA); for (const elem of setB) { _union.add(elem); } return _union;}function intersection(setA, setB) { const _intersection = new Set(); for (const elem of setB) { if (setA.has(elem)) { _intersection.add(elem); } } return _intersection;}function symmetricDifference(setA, setB) { const _difference = new Set(setA); for (const elem of setB) { if (_difference.has(elem)) { _difference.delete(elem); } else { _difference.add(elem); } } return _difference;}function difference(setA, setB) { const _difference = new Set(setA); for (const elem of setB) { _difference.delete(elem); } return _difference;}// 例const setA = new Set([1, 2, 3, 4]);const setB = new Set([2, 3]);const setC = new Set([3, 4, 5, 6]);isSuperset(setA, setB); // returns trueunion(setA, setC); // returns Set {1, 2, 3, 4, 5, 6}intersection(setA, setC); // returns Set {3, 4}symmetricDifference(setA, setC); // returns Set {1, 2, 5, 6}difference(setA, setC); // returns Set {1, 2}
配列との関係
const myArray = ["value1", "value2", "value3"];// 通常の Set コンストラクターを使用して、 Array を Set に変換const mySet = new Set(myArray);mySet.has("value1"); // returns true// スプレッド演算子を使って、集合を配列に変換console.log([...mySet]); // myArray と全く同じ Array が表示されます。
配列から重複した要素を取り除く
// 配列から重複する要素を取り除くために使用const numbers = [2, 13, 4, 4, 2, 13, 13, 4, 4, 5, 5, 6, 6, 7, 5, 32, 13, 4, 5];console.log([...new Set(numbers)]); // [2, 13, 4, 5, 6, 7, 32]
文字列との関係
// 大文字小文字の区別あり(集合に "F" と "f" が入る)new Set("Firefox"); // Set(7) [ "F", "i", "r", "e", "f", "o", "x" ]// 重複削除("f" は文字列中に 2 回現れるが、1 つしか入らない)new Set("firefox"); // Set(6) [ "f", "i", "r", "e", "o", "x" ]
Set を使用して、リスト中の値の一意性を保証
const array = Array.from(document.querySelectorAll("[id]")).map((e) => e.id);const set = new Set(array);console.assert(set.size === array.length);
仕様書
Specification |
---|
ECMAScript® 2026 Language Specification # sec-set-objects |