/** * 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 { 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): 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(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(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); } }