structs
Version:
A collection of general purpose data structures for JavaScript/TypeScript
237 lines (233 loc) • 7.54 kB
JavaScript
/*!
* structs v0.1.1
* A collection of general purpose data structures for JavaScript/TypeScript
* Copyright (c) 2021 Mayank Verma
* Released under the MIT License
*/
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
const Str = (value) => {
if (value === null || value === undefined)
return '';
if (typeof value === 'string')
return value;
return `${value}` === '0' && 1 / value === -Infinity ? '-0' : `${value}`;
};
var _HashSet_data;
class HashSet {
constructor(values = []) {
_HashSet_data.set(this, {});
values.forEach(value => this.insert(value));
}
/**
* @returns Length of the HashSet.
*/
len() {
return Object.keys(__classPrivateFieldGet(this, _HashSet_data, "f")).length;
}
/**
* Inserts value to the HashSet. If the value already exists in the HashSet it
* will return false, else true.
*
* @remarks
* This method throws an error if the provided value is not of valid type,
* i.e string, number or bigint.
*
* @param Value - Value to insert
* @param throwError - Boolean specifying whether to throw TypeError on invalid
* insert type or not, defaults to false.
* @returns boolean
*/
insert(value, throwError = false) {
const type = typeof value;
if (type !== 'string' && type !== 'number' && type !== 'bigint') {
if (throwError === true) {
throw new TypeError(`Cannot insert ${value} of type ${type} in a HashSet`);
}
else
return false;
}
if (Str(value) in __classPrivateFieldGet(this, _HashSet_data, "f")) {
return false;
}
__classPrivateFieldGet(this, _HashSet_data, "f")[Str(value)] = value;
return true;
}
/**
* Removes value from the HashSet. Returns true or false depending on whether
* given value was successfully removed from the HashSet or not.
*
* @param value - Value to remove
* @returns boolean
*/
remove(value) {
if (Str(value) in __classPrivateFieldGet(this, _HashSet_data, "f")) {
delete __classPrivateFieldGet(this, _HashSet_data, "f")[Str(value)];
return true;
}
return false;
}
/**
* Returns true or false depending on whether given value exists in
* the HashSet or not.
*
* @param value - Value to check
* @returns boolean
*/
contains(value) {
if (Str(value) in __classPrivateFieldGet(this, _HashSet_data, "f")) {
return true;
}
return false;
}
/**
* Clears the HashSet and returns all values in an iterator.
*
* @returns iterator
*/
drain() {
const data = __classPrivateFieldGet(this, _HashSet_data, "f");
this.clear();
return Object.values(data)[Symbol.iterator]();
}
/**
* Clears the HashSet and returns true.
*
* @returns true
*/
clear() {
__classPrivateFieldSet(this, _HashSet_data, {}, "f");
return true;
}
/**
* Returns values of HashSet in an array
*
* @returns array
*/
toArray() {
return Object.values(__classPrivateFieldGet(this, _HashSet_data, "f"));
}
/**
* Iterates over values of the HashSet and invokes the function for each value.
*
* @param function The function invoked per iteration.
* @returns null
*/
forEach(callback) {
for (const [_, value] of Object.entries(__classPrivateFieldGet(this, _HashSet_data, "f"))) {
callback(value);
}
return;
}
/**
* Performs union between two HashSets and returns the result in a new HashSet
*
* @param otherHashSet HashSet to perform union against
* @returns HashSet
*/
union(otherHashSet) {
return new HashSet([...this.toArray(), ...otherHashSet.toArray()]);
}
/**
* Performs intersection between two HashSets and returns the result in a new HashSet
*
* @param otherHashSet HashSet to perform intersection against
* @returns HashSet
*/
intersection(otherHashSet) {
const matchedValues = [];
otherHashSet.forEach(value => {
if (this.contains(value)) {
matchedValues.push(value);
}
});
return new HashSet(matchedValues);
}
/**
* Performs difference between two HashSets and returns the result in a new HashSet
*
* @param otherHashSet HashSet to perform difference against
* @returns HashSet
*/
difference(otherHashSet) {
const diff = [];
this.forEach(value => {
if (!otherHashSet.contains(value)) {
diff.push(value);
}
});
return new HashSet(diff);
}
/**
* Checks if two HashSets are equal
*
* @param otherHashSet HashSet to check equality against
* @returns boolean
*/
equals(otherHashSet) {
if (this.len() !== otherHashSet.len())
return false;
this.forEach(value => {
if (!otherHashSet.contains(value)) {
return false;
}
});
return true;
}
/**
* Checks if the HashSet is a subset of another HashSet
*
* @param otherHashSet HashSet to check against
* @returns boolean
*/
isSubsetOf(otherHashSet) {
if (this.len() > otherHashSet.len())
return false;
this.forEach(value => {
if (!otherHashSet.contains(value)) {
return false;
}
});
return true;
}
/**
* Checks if the HashSet is a strict subset of another HashSet
*
* @param otherHashSet HashSet to check against
* @returns boolean
*/
isStrictSubsetOf(otherHashSet) {
if (this.len() === otherHashSet.len())
return false;
return this.isSubsetOf(otherHashSet);
}
/**
* Checks if the HashSet is a superset of another HashSet
*
* @param otherHashSet HashSet to check against
* @returns boolean
*/
isSupersetOf(otherHashSet) {
return otherHashSet.isSubsetOf(this);
}
/**
* Checks if the HashSet is a strict superset of another HashSet
*
* @param otherHashSet HashSet to check against
* @returns boolean
*/
isStrictSupersetOf(otherHashSet) {
return otherHashSet.isStrictSubsetOf(this);
}
}
_HashSet_data = new WeakMap();
export { HashSet };