UNPKG

structs

Version:

A collection of general purpose data structures for JavaScript/TypeScript

237 lines (233 loc) 7.54 kB
/*! * 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 };