sussy-util
Version:
Util package made by me
227 lines (226 loc) • 8.97 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require(".");
/**
* A custom Set implementation that ensures unique items with flexible equality checks.
* @template T - The type of items stored in the Set.
*/
class Set {
/**
* Constructs a new Set instance.
* @param {T[]} items - The initial items to populate the set.
* @param {CheckFunction<T>} [checkFunction] - Optional equality check function.
*/
constructor(items, checkFunction) {
this.items = new _1.ImprovedArray();
this.checkFunction = (a, b) => a === b;
/**
* Adds an item to the set if it does not already exist.
* @param {T} item - The item to add.
*/
this.push = (item) => {
if (this.has(item))
return;
this.items.push(item);
};
/**
* Removes an item from the set.
* @param {T} item - The item to remove.
* @returns {boolean} - True if the item was removed, false otherwise.
*/
this.delete = (item) => {
const index = this.items.indexOf(item);
if (index < 0)
return false;
this.items.remove(index);
return true;
};
/**
* Retrieves the item at a given index as an Optional.
* @param {number} index - The index of the item.
* @returns {Optional<T>} - The item wrapped in an Optional.
*/
this.get = (index) => {
if (index < 0 || index >= this.length())
return _1.Optional.empty();
return _1.Optional.of(this.items[index]);
};
/**
* Checks if the set is empty.
* @returns {boolean} - True if the set is empty, false otherwise.
*/
this.isEmpty = this.items.isEmpty.bind(this.items);
/**
* Returns the number of items in the set.
* @returns {number} - The number of items in the set.
*/
this.length = () => this.items.length;
/**
* Clears all items from the set.
*/
this.clear = this.items.clear.bind(this.items);
/**
* Creates a new Set with the same items.
* @returns {Set<T>} - A clone of the current set.
*/
this.clone = () => new Set(this.items, this.checkFunction);
/**
* Removes an item at a given index.
* @param {number} index - The index of the item to remove.
* @returns {boolean} - True if the item was removed, false otherwise.
*/
this.remove = (index) => {
if (index < 0 || index >= this.length())
return false;
this.items.remove(index);
return true;
};
/**
* Converts the set to an array.
* @returns {T[]} - An array representation of the set.
*/
this.toArray = this.items.clone.bind(this.items);
/**
* Changes the equality check function.
* @param {CheckFunction<T>} predicate - The new equality check function.
*/
this.changeCheckFunction = (predicate) => {
this.checkFunction = predicate;
};
/**
* Returns a string representation of the set.
* @returns {string} - The string representation of the set.
*/
this.toString = () => `Set: ${this.items.toString()}`;
/**
* Returns a JSON string representation of the set.
* @returns {string} - The JSON string representation of the set.
*/
this.toJSONString = () => this.items.toJSONString();
/**
* Checks if the set contains an item.
* @param {T} item - The item to check for.
* @returns {boolean} - True if the item is in the set, false otherwise.
*/
this.has = (item) => this.items.some(this.checkFunction.bind(this, item));
/**
* Executes a callback function for each item in the set.
* @param {CallBack<T>} callback - The callback function.
*/
this.forEach = (callback) => this.items.forEach(callback);
/**
* Executes a callback function for each item in the set (alias for `forEach`).
* @param {CallBack<T>} callback - The callback function.
*/
this.each = (callback) => this.forEach(callback);
/**
* Merges another set with this set.
* @param {Set<T>} set - The set to merge.
* @returns {Set<T>} - A new set containing all items from both sets.
*/
this.merge = (set) => {
return new Set([...this.items, ...set.toArray()], this.checkFunction);
};
/**
* Returns a new set containing items present in this set but not in the provided set.
* @param {Set<T>} set - The set to subtract.
* @returns {Set<T>} - A new set with subtracted items.
*/
this.subtract = (set) => {
const subtractedItems = this.items.filter((item) => !set.has(item));
return new Set(subtractedItems, this.checkFunction);
};
/**
* Filters the set based on a predicate.
* @param {(item: T, index: number) => boolean} predicate - The predicate function.
* @returns {Set<T>} - A new set with items that satisfy the predicate.
*/
this.filter = (predicate) => {
const filteredItems = [];
this.forEach((item, i) => {
if (!predicate(item, i))
return;
filteredItems.push(item);
});
return new Set(filteredItems, this.checkFunction);
};
/**
* Reduces the set to a single value using a reducer function.
* @template U
* @param {(accumulator: U, currentItem: T, index: number) => U} reducer - The reducer function.
* @param {U} initialValue - The initial value for the accumulator.
* @returns {U} - The final accumulated value.
*/
this.reduce = (reducer, initialValue) => {
let accumulator = initialValue;
this.forEach((item, i) => {
accumulator = reducer(accumulator, item, i);
});
return accumulator;
};
/**
* Maps each item in the set to a new value, ensuring uniqueness of mapped items.
* @template U
* @param {(item: T, index: number) => U} callback - The mapping function.
* @returns {Set<U>} - A new set with mapped items.
*/
this.map = (callback) => {
const mappedItems = [];
this.forEach((item, i) => {
const newItem = callback(item, i);
mappedItems.push(newItem);
});
return new Set(mappedItems, (a, b) => a === b);
};
/**
* Returns a new set containing items present in both this set and another set.
* @param {Set<T>} set - The set to intersect with.
* @returns {Set<T>} - A new set with intersected items.
*/
this.intersection = (set) => {
const intersectionItems = this.items.filter((item) => set.has(item));
return new Set(intersectionItems, this.checkFunction);
};
/**
* Returns a new set containing all unique items from both sets.
* @param {Set<T>} set - The set to unite with.
* @returns {Set<T>} - A new set with union items.
*/
this.union = (set) => {
return new Set([...this.items, ...set.toArray()], this.checkFunction);
};
/**
* Returns a new set containing items that are in either set, but not both.
* @param {Set<T>} set - The set to compare with.
* @returns {Set<T>} - A new set with symmetric difference items.
*/
this.symmetricDifference = (set) => {
const itemsInThisNotInOther = this.items.filter((item) => !set.has(item));
const itemsInOtherNotInThis = set.toArray().filter((item) => !this.has(item));
return new Set([...itemsInThisNotInOther, ...itemsInOtherNotInThis], this.checkFunction);
};
if (checkFunction)
this.checkFunction = checkFunction;
items.forEach((item) => {
if (!this.has(item))
this.items.push(item);
});
}
/**
* Enables iteration over the set using `for...of`.
* @returns {Iterator<T>} - An iterator for the set.
*/
[Symbol.iterator]() {
let index = 0;
const items = [...this.items];
return {
next() {
if (index < items.length) {
return { value: items[index++], done: false };
}
return { value: undefined, done: true };
},
};
}
}
exports.default = Set;