コンテンツにスキップ

JavaScript/Set

出典: フリー教科書『ウィキブックス(Wikibooks)』
JavaScript > 標準ライブラリ Set

Setオブジェクト

[編集]

Setオブジェクトは集合を扱うための機能を組み込んだオブジェクトです。 Setオブジェクトの生成には、Setコンストラクターを使います。

const set = new Set()

Setオブジェクトにはリテラルはありません。

コード例

[編集]
コード例
const set1 = new Set() ; console.log(set1)

set1.add(1)            ; console.log(set1)
set1.add("a")          ; console.log(set1)
set1.add(1)            ; console.log(set1)
set1.add([1,2,3])      ; console.log(set1)
set1.delete(1)         ; console.log(set1)
set1.delete(1)         ; console.log(set1)
set1.add(1)            ; console.log(set1)
console.log(`set1.has(1) = ${set1.has(1)}, set1.has(2) = ${set1.has(2)}`)
console.log([...set1])
console.log([...set1.values()])
console.log([...set1.keys()])
console.log([...set1.entries()])
set1.forEach(x => console.log(x))
set1.clear(set1)       ; console.log(set1)

const a = new Set()
const b = new Set()
a.add(100)
b.add(100)
console.log(a == b)
実行結果
Set(0) {}
Set(1) { 1 }
Set(2) { 1, 'a' }
Set(2) { 1, 'a' }
Set(3) { 1, 'a', [ 1, 2, 3 ] }
Set(2) { 'a', [ 1, 2, 3 ] }
Set(2) { 'a', [ 1, 2, 3 ] }
Set(3) { 'a', [ 1, 2, 3 ], 1 }
set1.has(1) = true, set1.has(2) = false
[ 'a', [ 1, 2, 3 ], 1 ]
[ 'a', [ 1, 2, 3 ], 1 ]
[ 'a', [ 1, 2, 3 ], 1 ]
[ [ 'a', 'a' ], [ [ 1, 2, 3 ], [ 1, 2, 3 ] ], [ 1, 1 ] ]
a
[ 1, 2, 3 ]
1
Set(0) {}
false
存在しない要素をdeleteしても例外は上がりません。
Setオブジェクトは集合ですが、JavaScriptは演算子オーバーロードはできないので集合同士に比較演算子は適用できません。
また、集合演算にも対応しておらず、和集合(union)・積集合(intersection)・差集合(difference)・部分集合か判定(issubset)・上位集合(issuperset)・排他判定(isdisjoint)などのメソッドは用意されていません[1]

Polyfill

[編集]

集合演算関係のメソッド追加提案は既にTC39に提出されていますが[2]、参考までに Polyfill を書いてみました。

Polyfill
Object.entries({
    filter: function (callback) {
        if (typeof callback !== 'function')
            throw new TypeError();
        
        const result = new Set()
        for (const x of this)
            if (callback(x))
                result.add(x)
        return result
    },
    map: function (callback) {
        if (typeof callback !== 'function')
            throw new TypeError();
        
        const result = new Set()
        for (const x of this)
            result.add(callback(x))
        return result
    },
    reduce: function (callback, initial) {
        if (typeof callback !== 'function')
            throw new TypeError();
        let result = initial
        for (const x of this) {
            if (result === undefined)
                result = x
            else
                result = callback(result, x, this)
        }
        return result
    },
    union: function (other) {
        const result = new Set(this)
        for (const x of other) {
            result.add(x)
        }
        return result
    },
    intersection: function (other) {
        return this.filter(e => other.has(e))
    },
    difference: function (other) {
        return this.filter(e => !other.has(e))
    },
    superset_p: function (other) {
        for (const elem of other) {
            if (!this.has(elem)) {
                return false
            }
        }
        return true
    },
    subset_p: function (other) {
        return other.superset_p(this)
    },
}).forEach(pair => {
    const [method, func] = pair
    Object.defineProperty(Set.prototype, method, {
        value: func
    })
})

const a = new Set([0, 1, 2]),
    b = new Set([2, 3, 4]),
    c = new Set([0, 1, 2, 3, 4, 5, 6])

const ary = [
    "a",
    "b",
    "c",
    "a.map(x => x * 2)",
    "a.union(b)",
    "a.intersection(b)",
    "a.difference(b)",
    "a.superset_p(c)",
    "a.subset_p(c)",
]
ary.forEach(x => console.log(x, "=>", eval(x)))
実行結果
a => Set(3) { 0, 1, 2 }
b => Set(3) { 2, 3, 4 }
c => Set(7) { 0, 1, 2, 3, 4, 5, 6 }
a.map(x => x * 2) => Set(3) { 0, 2, 4 }
a.union(b) => Set(5) { 0, 1, 2, 3, 4 }
a.intersection(b) => Set(1) { 2 }
a.difference(b) => Set(2) { 0, 1 }
a.superset_p(c) => false
a.subset_p(c) => true

プロパティ

[編集]

静的プロパティ

[編集]
Set.length
1
コンストラクタの引数の数
Set.name
"Set"
Set.prototype
[object]

静的メソッド

[編集]

インスタンスプロパティ

[編集]

Set.prototype.size

[編集]

Setオブジェクトの要素数。

インスタンスメソッド

[編集]

この節は書きかけです。この節を編集してくれる方を心からお待ちしています。

Set.prototype.add(item)

[編集]

Set.prototype.clear()

[編集]

Set.prototype.constructor()

[編集]

Set.prototype.delete(item)

[編集]

Set.prototype.entries()

[編集]

Set.prototype.forEach(func)

[編集]

Set.prototype.has(item)

[編集]

Set.prototype.keys()

[編集]

Set.prototype.values()

[編集]

Set Helpers

[編集]

ES(ECMAScript)の Set Helpers は、Set オブジェクトに対して便利な操作を追加する提案で、集合データ(重複しない要素のコレクション)をより簡単かつ直感的に操作できるようにするための新機能です。この提案は、配列やオブジェクトにある便利なメソッドを Set にも拡張し、集合演算やフィルタリングなどの操作を簡潔に実現します。

背景

[編集]

現在の Set オブジェクトは、add, delete, has といった基本的な操作しかサポートしていません。そのため、集合データの操作(例えば、和集合、差集合、交差集合など)を行うには、手動でループやメソッドを組み合わせる必要があり、冗長なコードになることがあります。

Set Helpers はこれを解消し、Set オブジェクトを扱いやすくする新しいメソッドを提供します。

主なメソッド

[編集]

union

[編集]

他のセットと「和集合」を作成します。

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

const unionSet = setA.union(setB);
console.log(unionSet); // Set { 1, 2, 3, 4, 5 }

intersection

[編集]

他のセットと「共通部分(交差集合)」を作成します。

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

const intersectionSet = setA.intersection(setB);
console.log(intersectionSet); // Set { 3 }

difference

[編集]

他のセットとの差集合を作成します。

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

const differenceSet = setA.difference(setB);
console.log(differenceSet); // Set { 1, 2 }

symmetricDifference

[編集]

「対称差集合」(どちらか一方のセットにしか含まれない要素)を作成します。

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

const symmetricDifferenceSet = setA.symmetricDifference(setB);
console.log(symmetricDifferenceSet); // Set { 1, 2, 4, 5 }

isSubsetOf

[編集]

あるセットが他のセットの部分集合かをチェックします。

const setA = new Set([1, 2]);
const setB = new Set([1, 2, 3]);

console.log(setA.isSubsetOf(setB)); // true

isSupersetOf

[編集]

あるセットが他のセットを包含しているかをチェックします。

const setA = new Set([1, 2, 3]);
const setB = new Set([1, 2]);

console.log(setA.isSupersetOf(setB)); // true

map

[編集]

各要素を変換して新しい Set を作成します。

const setA = new Set([1, 2, 3]);

const mappedSet = setA.map(x => x * 2);
console.log(mappedSet); // Set { 2, 4, 6 }

filter

[編集]

条件を満たす要素だけを含む新しい Set を作成します。

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

const filteredSet = setA.filter(x => x % 2 === 0);
console.log(filteredSet); // Set { 2, 4 }

reduce

[編集]

集合の要素を1つの値にまとめます。

const setA = new Set([1, 2, 3]);

const sum = setA.reduce((acc, x) => acc + x, 0);
console.log(sum); // 6

使用例: 組み合わせ

[編集]

Set Helpers を使うことで、複雑な操作もシンプルに記述できます。

const setA = new Set([1, 2, 3, 4]);
const setB = new Set([3, 4, 5, 6]);

const result = setA
  .union(setB)                // 和集合 { 1, 2, 3, 4, 5, 6 }
  .filter(x => x % 2 === 0)   // 偶数だけ { 2, 4, 6 }
  .map(x => x * 10);          // 各要素を10倍 { 20, 40, 60 }

console.log(result); // Set { 20, 40, 60 }

メリット

[編集]
  1. 簡潔なコード: 従来の冗長なループ処理が不要。
  2. 統一された操作: 他のデータ構造(配列やマップ)と同様のメソッドが使用可能。
  3. 効率的な集合演算: 集合に特化したメソッドを活用。


状態

[編集]

Set Helpers はまだ仕様策定中であり、最新の ECMAScript 提案(Stage 2 または Stage 3)に含まれています。一部のブラウザや JavaScript ランタイム(例えば、Node.js)では試験的に実装されている場合があります。使用する際は、環境の対応状況を確認してください。

このように、Set Helpers は JavaScript における集合操作を簡単にし、開発者の負担を大幅に軽減することを目指しています。

脚註

[編集]
  1. ^ Set - JavaScript // MDN” (2021年12月8日). 2021年12月26日閲覧。
  2. ^ New Set methods” (2019年). 2021年12月26日閲覧。

外部リンク

[編集]