Uecko_ERP/packages/rdx-utils/src/helpers/collection.ts
2025-10-12 12:43:06 +02:00

151 lines
4.5 KiB
TypeScript

/**
* Clase genérica para manejar una colección de elementos.
* Ofrece métodos básicos para manipular, consultar y recorrer los elementos.
*/
export class Collection<T> {
protected items: T[];
protected totalItems: number;
/**
* Crea una nueva colección.
* @param items - Elementos iniciales de la colección.
* @param totalItems - Total de elementos esperados (opcional). Si no se define, se usa la longitud del array inicial.
*/
constructor(items: T[] = [], totalItems: number | null = null) {
this.items = [...items];
this.totalItems = totalItems ?? items.length;
}
/**
* Vacía la colección y reinicia el total de elementos.
*/
reset(): void {
this.items = [];
this.totalItems = 0;
}
/**
* Agrega un nuevo elemento a la colección.
* @param item - Elemento a agregar.
*/
addCollection(collection: Collection<T>): boolean {
this.items.push(...collection.items);
if (this.totalItems !== null) {
this.totalItems = this.totalItems + collection.totalItems;
}
return true;
}
/**
* Agrega un nuevo elemento a la colección.
* @param item - Elemento a agregar.
*/
add(item: T): boolean {
this.items.push(item);
if (this.totalItems !== null) {
this.totalItems++;
}
return true;
}
/**
* Elimina un elemento de la colección, si existe.
* @param item - Elemento a eliminar.
* @returns `true` si el elemento fue eliminado, `false` si no se encontró.
*/
remove(item: T): boolean {
const index = this.items.indexOf(item);
return this.removeByIndex(index);
}
removeByIndex(index: number) {
if (index !== -1) {
this.items.splice(index, 1);
if (this.totalItems !== null) {
this.totalItems--;
}
return true;
}
return false;
}
/**
* Devuelve una copia de todos los elementos de la colección.
* @returns Array de elementos.
*/
getAll(): T[] {
return [...this.items];
}
/**
* Devuelve la cantidad actual de elementos en la colección.
* @returns Número de elementos presentes.
*/
size(): number {
return this.items.length;
}
/**
* Devuelve el total de elementos esperados en la colección.
* Puede diferir de `size()` si los datos son paginados, por ejemplo.
* @returns Número total o `null` si no se especificó.
*/
total(): number {
return this.totalItems;
}
/**
* Performs the specified action for each element in an array.
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
forEach<U>(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void {
this.items.forEach(callbackfn);
}
/**
* Aplica una función a cada elemento y devuelve un nuevo array con los resultados.
* @param callback - Función transformadora.
* @returns Nuevo array con los elementos transformados.
*/
map<U>(callback: (item: T, index: number, array: T[]) => U): U[] {
return this.items.map(callback);
}
/**
* Devuelve un array con los elementos que cumplen la condición del callback.
* @param callback - Función de filtrado.
* @returns Nuevo array con los elementos filtrados.
*/
filter(callback: (item: T, index: number, array: T[]) => boolean): T[] {
return this.items.filter(callback);
}
/**
* Devuelve el primer elemento que cumple la condición del callback.
* @param callback - Función de búsqueda.
* @returns El primer elemento que cumple la condición, o `undefined` si no hay coincidencias.
*/
find(callback: (item: T, index: number, array: T[]) => boolean): T | undefined {
return this.items.find(callback);
}
/**
* Verifica si al menos un elemento cumple la condición dada.
* @param callback - Función de evaluación.
* @returns `true` si al menos un elemento cumple, `false` en caso contrario.
*/
some(callback: (item: T, index: number, array: T[]) => boolean): boolean {
return this.items.some(callback);
}
/**
* Verifica si todos los elementos cumplen la condición dada.
* @param callback - Función de evaluación.
* @returns `true` si todos cumplen, `false` si alguno no.
*/
every(callback: (item: T, index: number, array: T[]) => boolean): boolean {
return this.items.every(callback);
}
}