'use strict';
/**
* Creates a Set instance.
* @constructor
*/
function Set() {
this.set = {};
this.numElems = 0;
}
/**
* Get the number of elements in the set.
* @returns {number} Number of elements in the set.
*/
Set.prototype.size = function() {
return this.numElems;
};
/**
* Returns whether the set is empty.
* @returns {boolean} Whether or not the set is empty.
*/
Set.prototype.isEmpty = function() {
return this.numElems === 0;
};
/**
* Clears the elements in the set.
* Results in a set equal to a newly constructed instance.
*/
Set.prototype.clear = function() {
this.set = {};
this.numElems = 0;
};
/**
* Extract a key from an object for the set dictionary.
* @param {elem} elem - A graphics object to get a key for.
* @returns {string} A string representing the elen.
*/
Set.prototype.getKey = function(elem) {
var name = elem;
if (typeof elem == 'object') name = elem.toString();
return name;
};
/**
* Add an object to a set.
* @param {elem} elem - A graphics object to be added.
*/
Set.prototype.add = function(elem) {
if (elem === null) {
throw new TypeError('Cannot add a null to a set.');
}
var key = this.getKey(elem);
if (!this.containsKey(key)) {
this.numElems++;
}
this.set[key] = elem;
};
/**
* Remove an object from a set.
* @param {elem} elem - A graphics object to be removed.
*/
Set.prototype.remove = function(elem) {
if (elem === null) {
throw new TypeError('Cannot remove null from a set.');
}
var key = this.getKey(elem);
if (this.containsKey(key)) {
delete this.set[key];
this.numElems--;
} else {
throw new Error('Set does not contain ' + key);
}
};
/**
* Check if a set contains a key.
* @return {boolean} Whether or not the set contains the key.
*/
Set.prototype.containsKey = function(key) {
return typeof this.set[key] != 'undefined';
};
/**
* Check if a set contains an elem.
* @param {elem} elem - A graphics object to be checked.
* @return {boolean} Whether or not the set contains the elem.
*/
Set.prototype.contains = function(elem) {
return typeof this.find(elem) != 'undefined';
};
/**
* Get the items in the set.
* @returns {dictionary} Dictionary of all items in the set
*/
Set.prototype.elems = function() {
return this.set;
};
/**
* Finds an elem in the set.
* @param {elem} elem - An element to look for.
* @returns {elem|undefined} Either the element (if found) or undefined.
*/
Set.prototype.find = function(elem) {
var key = this.getKey(elem);
return this.set[key];
};
/**
* Creates a union between two sets.
* @param {Set} otherSet - A set with which a union should be created.
*/
Set.prototype.union = function(otherSet) {
for (var key in otherSet.elems()) {
this.add(otherSet.find(key));
}
};
/**
* Remove items from the set if they are not contained in otherSet.
* @param {Set} otherSet - A set with which an intersection should be created.
*/
Set.prototype.intersect = function(otherSet) {
var newElems = {};
var newSize = 0;
for (var key in otherSet.elems()) {
if (this.containsKey(key)) {
newSize++;
newElems[key] = this.find(key);
}
}
this.set = newElems;
this.numElems = newSize;
};
/**
* Create a string representation of the set.
* @returns {string} String representation of the set
* Follows the syntax 'Set: {elem, elem, elem}'
*/
Set.prototype.toString = function() {
var result = 'Set: {';
var i = 0;
for (var key in this.set) {
var cur = this.set[key];
result += cur;
if (i < this.size() - 1) {
result += ', ';
}
i++;
}
result += '}';
return result;
};
module.exports = Set;