JavaScript
ECMAScript2015
More than 1 year has passed since last update.

JavaScriptで集合演算がしたくて調べてみたら、ECMAScript2015(es6)からbuilt-in objectとしてSetが用意されていることがわかった(MDN Set (日本語版))。集合の定義と要素の追加や削除、イテレータの例は日本語版にあるが、和や積などの集合演算の例は英語版にしか無かった。試してみたのでメモを共有。

集合演算の定義

英語版によると、組み込みでは集合演算は定義されていないので、自分で追加する必要がある。上位集合(Superset)、和(Union)、積(intersection)、差(difference)の例がある。

上位集合(Superset)

superset.js
Set.prototype.isSuperset = function(subset) {
    for (var elem of subset) {
        if (!this.has(elem)) {
            return false;
        }
    }
    return true;
}

和(Union)

union.js
Set.prototype.union = function(setB) {
    var union = new Set(this);
    for (var elem of setB) {
        union.add(elem);
    }
    return union;
}

積(Intersection)

intersection.js
Set.prototype.intersection = function(setB) {
    var intersection = new Set();
    for (var elem of setB) {
        if (this.has(elem)) {
            intersection.add(elem);
        }
    }
    return intersection;
}

差(Difference)

difference.js
Set.prototype.difference = function(setB) {
    var difference = new Set(this);
    for (var elem of setB) {
        difference.delete(elem);
    }
    return difference;
}

部分集合がなかったので書いてみた。上位集合の裏返しなので、下記のような感じになるはず。

subset.js
Set.prototype.isSubset = function(superset) {
    for (var elem of this) {
        if (!superset.has(elem)) {
            return false;
        }
    }
    return true;
}

実行

公式の例をChromeのJavaScript Consoleで試してみた。

example1.js
//Examples
var setA = new Set([1, 2, 3, 4]),
    setB = new Set([2, 3]),
    setC = new Set([3, 4, 5, 6]);

setA.isSuperset(setB);
// true

setA.union(setC);
// Set(6) {1, 2, 3, 4, 5, 6}

setA.intersection(setC);
// Set(2) {3, 4}

setA.difference(setC);
// Set(2) {1, 2}

部分集合も試してみた

example2.js
setA.isSubset(setB);
// false

setB.isSubset(setA);
// true

期待したとおり動いているようだ。

感想

やっぱり、組み込みでサポートしてくれるととても便利。演算も、和、積は組み込んでほしいと思った。

参考