はじめに
JavaScriptやTypeScriptで集合演算をしようと思って調べてみると、ES6以降Set
は導入されているものの、これらの演算はbuilt-inで実装されていないようでした。
これっていうイディオムないんかと調べてみても、for文でどうのこうのとか、lodashを使いましょうとか、とてもじゃないですが納得できない…。
自分の中で、まぁこれなら許せるかという書き方について備忘しておきます。
Union(和集合)
const x = new Set([1, 2, 3]);
const y = new Set([2, 3, 4]);
const union = new Set([...x, ...y]); //1, 2, 3, 4
配列としてひっつけて、Set
にいれなおしてるだけです。
Intersection(積集合)
const x = new Set([1, 2, 3]);
const y = new Set([2, 3, 4]);
const intersection = new Set([...x].filter(e => (y.has(e)))); //2, 3
配列に倒してfilterして、Set
にいれなおす。
Difference(差集合)
const x = new Set([1, 2, 3]);
const y = new Set([2, 3, 4]);
const difference = new Set([...x].filter(e => (!y.has(e)))); //1
積集合とほぼ同じです。filterの条件が積のときと逆です。
Product(直積集合)
const x = new Set([1, 2, 3]);
const y = new Set([2, 3, 4]);
const product = new Set(
[...x]
.map(e0 => (y.map(e1 => ([e0, e1]))))
.reduce((acc, e) => ([...acc, ...e]), []));
map
で組み合わせを作って、reduce
でフラット化しています。
おまけ
上記でも使っていますが、Array
とSet
の相互変換です。
const a = new Set([1, 2, 3]) // array to set
const b = [...a] //set to array
さいごに
タプルもないんか…。