@technobuddha/library
Version:
A large library of useful functions
178 lines • 9.71 kB
JavaScript
import { jsonDeserialize } from "./json-deserialize.js";
import { jsonSerialize } from "./json-serialize.js";
/**
* A Set-like collection for objects that can be serialized to JSON.
*
* `JSONSet` stores objects by serializing them to JSON strings, allowing for deep equality
* comparison of objects rather than reference equality. This is useful for storing and comparing
* objects with the same structure and values, regardless of their references.
* @typeParam T - The type of objects stored in the set. Must extend `JsonObject`.
* @example
* ```typescript
* const set = new JSONSet<{ a: number }>();
* set.add({ a: 1 });
* set.has({ a: 1 }); // true
* set.has({ a: 2 }); // false
* ```
* @remarks
* - All objects are serialized using a `serialize` function and deserialized with a `deserialize` function.
* - The set supports standard set operations such as union, intersection, difference, and symmetricDifference.
* - Iteration yields deserialized objects.
* @see Set
* @group JSON
* @category Data Structures
*/
export class JSONSet {
set = new Set();
constructor(values) {
if (values) {
for (const value of values) {
this.add(value);
}
}
}
/**
* The string tag used by Object.prototype.toString for this class.
*/
[Symbol.toStringTag] = 'JSONSet';
replicate(values) {
const Maker = this.constructor;
return new Maker(values);
}
/**
* Gets the number of elements in the set.
*/
get size() {
return this.set.size;
}
/**
* Adds a serialized value to the set.
*/
add(value) {
this.set.add(jsonSerialize(value));
return this;
}
/**
* Removes all elements from the set.
*/
clear() {
this.set.clear();
}
/**
* Removes the specified value from the set if it exists.
*/
delete(value) {
return this.set.delete(jsonSerialize(value));
}
/**
* Returns a new set containing elements present in this set but not in the other set.
*/
difference(other) {
return this.replicate(Array.from(this.values()).filter((value) => !other.has(value)));
}
/**
* Returns an iterator over the set's values as [value, value] pairs.
*/
*entries() {
for (const value of this.values()) {
yield [value, value];
}
}
/**
* Executes a provided function once for each value in the set.
*/
forEach(callback, thisArg) {
for (const value of this.values()) {
callback.call(thisArg, value, value, this);
}
}
/**
* Determines whether the specified value exists in the set.
*/
has(value) {
return this.set.has(jsonSerialize(value));
}
/**
* Returns a new set containing only the elements present in both this set and the provided set.
*/
intersection(other) {
return this.replicate(Array.from(this.values()).filter((value) => other.has(value)));
}
/**
* Determines whether this set and the specified set have no elements in common.
*/
isDisjointFrom(other) {
for (const value of this.values()) {
if (other.has(value)) {
return false;
}
}
return true;
}
/**
* Determines whether all elements of this set are contained in another set.
*/
isSubsetOf(other) {
for (const value of this.values()) {
if (!other.has(value)) {
return false;
}
}
return true;
}
/**
* Determines whether this set contains all elements of the specified set.
*/
isSupersetOf(other) {
for (const value of other.keys()) {
if (!this.has(value)) {
return false;
}
}
return true;
}
/**
* Returns an iterator over the keys in the set.
*/
*keys() {
yield* this.values();
}
/**
* Returns a new set containing elements that are in either this set or the other set, but not in both.
*/
symmetricDifference(other) {
const result = this.replicate();
for (const value of this.keys()) {
if (!other.has(value)) {
result.add(value);
}
}
for (const value of other.keys()) {
if (!this.has(value)) {
result.add(value);
}
}
return result;
}
/**
* Returns a new set containing all unique elements from this set and another set.
*/
union(other) {
return this.replicate([...this.keys(), ...other.keys()]);
}
/**
* Returns an iterator that yields each value in the set after deserialization.
*/
*values() {
for (const object of this.set) {
yield jsonDeserialize(object);
}
}
/**
* Returns an iterator over the values in the set.
*/
[Symbol.iterator]() {
return this.values();
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvanNvbi1zZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVwRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFDUixHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUVsQyxZQUFtQixNQUEyQjtRQUM1QyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNsQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNhLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUV2QyxTQUFTLENBQVEsTUFBMkI7UUFDcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQTBELENBQUM7UUFDOUUsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFXLElBQUk7UUFDYixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNJLEdBQUcsQ0FBQyxLQUFRO1FBQ2pCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSztRQUNWLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ks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