Generalize the CellSet type into a general-purpose Set
This commit is contained in:
parent
ac7cd6333b
commit
71c405e5cd
1 changed files with 69 additions and 0 deletions
69
js/Set.js
Normal file
69
js/Set.js
Normal file
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in a new issue