From 71c405e5cdbc62963849f15550cf6690c10600b5 Mon Sep 17 00:00:00 2001 From: Tissevert Date: Sat, 20 Aug 2022 16:23:50 +0200 Subject: [PATCH] Generalize the CellSet type into a general-purpose Set --- js/Set.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 js/Set.js diff --git a/js/Set.js b/js/Set.js new file mode 100644 index 0000000..fa6d264 --- /dev/null +++ b/js/Set.js @@ -0,0 +1,69 @@ +return { + make: make +}; + +function make(type) { + if(type == undefined) { + var id = function(x) {return x;}; + type = {toKey: id, ofKey: id}; + } + + function Set(s) { + this.elements = {}; + if(Array.isArray(s)) { + s.forEach(this.add.bind(this)); + } else if(s != undefined) { + this.add(s); + } + } + + Set.prototype.add = function(e) { this.elements[type.toKey(e)] = true; }; + Set.prototype.remove = function(e) { delete this.elements[type.toKey(e)]; }; + Set.prototype.contains = function(e) { return !!this.elements[type.toKey(e)]; }; + Set.prototype.size = function() { return Object.keys(this.elements).length; }; + + Set.prototype.toList = function() { + var result = []; + for(var k in this.elements) { + result.push(type.ofKey(k)); + } + return Array.from(result).sort(); + } + + Set.prototype.iter = function(f) { this.toList().forEach(f); }; + Set.prototype.map = function(f) { return this.toList().map(f); }; + + Set.prototype.equals = function(set) { + var sorted = [this.toList(), set.toList()]; + return sorted[0].length == sorted[1].length && + sorted[0].every(function(x) {return x == sorted[1].shift();}); + } + + Set.prototype.subset = function(predicate) { + var newSet = new Set(); + this.iter(function(e) { + if(predicate(e)) { + newSet.add(e); + } + }); + return newSet; + }; + + Set.prototype.difference = function(set) { + return this.subset(function(e) {return !set.contains(e);}); + } + + Set.prototype.intersection = function(set) { + return this.subset(function(e) {return set.contains(e);}); + } + + Set.union = function(sets) { + var newSet = new Set(); + for(var i = 0; i < sets.length; i++) { + sets[i].iter(newSet.add.bind(newSet)); + } + return newSet; + } + + return Set; +}