UNPKG

tipazo

Version:

libreria-multiform

137 lines (116 loc) 4.88 kB
//elimina los duplicados export function removeAdvancedDuplicates<T>(arr: T[]): T[] { const seen = new Set<string>(); return arr.filter(item => { const key = JSON.stringify(item); if (seen.has(key)) return false; seen.add(key); return true; }); } //muestra los duplicados export function findDuplicates<T>(arr: T[]): T[] { const seen = new Set<string>(); const duplicates: T[] = []; for (const item of arr) { const key = JSON.stringify(item); if (seen.has(key)) { duplicates.push(item); } else { seen.add(key); } } return duplicates; } //cuenta duplicado export function countDuplicates<T>(arr: T[]): Map<string, number> { const countMap = new Map<string, number>(); for (const item of arr) { const key = JSON.stringify(item); countMap.set(key, (countMap.get(key) || 0) + 1); } return countMap; } export function countTotalDuplicates<T>(arr: T[]): number { const seen = new Set<string>(); let duplicateCount = 0; for (const item of arr) { const key = JSON.stringify(item); if (seen.has(key)) { duplicateCount++; } else { seen.add(key); } } return duplicateCount; } export function agruparPorClave<T extends Record<string, any>>(datos: T[], clave: string): Record<string, T[]> { return datos.reduce((grupo, item) => { const valor = item[clave]; if (!grupo[valor]) grupo[valor] = []; grupo[valor].push(item); return grupo; }, {} as Record<string, T[]>); } export function resumenNumerico(datos: Record<string, any>[], clave: string) { const valores = datos.map(d => d[clave]).filter(v => typeof v === 'number'); const total = valores.reduce((a, b) => a + b, 0); const promedio = total / valores.length; const max = Math.max(...valores); const min = Math.min(...valores); return { total, promedio, max, min }; } export function filtrarPorRangoDeFechas( datos: Record<string, any>[], claveFecha: string, desde: Date, hasta: Date ): Record<string, any>[] { return datos.filter(item => { const fecha = new Date(item[claveFecha]); return fecha >= desde && fecha <= hasta; }); } export function detectarOutliers<T extends Record<string, any>>(datos: T[], clave: string): T[] { const valores = datos.map(d => d[clave]).filter(v => typeof v === 'number').sort((a, b) => a - b); const q1 = valores[Math.floor(valores.length / 4)]; const q3 = valores[Math.floor((valores.length * 3) / 4)]; const iqr = q3 - q1; const min = q1 - 1.5 * iqr; const max = q3 + 1.5 * iqr; return datos.filter(d => { const valor = d[clave]; return typeof valor === 'number' && (valor < min || valor > max); }); } export function generarResumenNarrativo<T extends Record<string, any>>(datos: T[], claveNombre: string, claveValor: string): string { if (!datos.length) return 'No hay datos disponibles para generar el resumen.'; const total = datos.reduce((sum, item) => sum + item[claveValor], 0); const promedio = total / datos.length; const ordenados = [...datos].sort((a, b) => b[claveValor] - a[claveValor]); const top = ordenados[0]; const lista = datos.map(d => `${d[claveNombre]} (${d[claveValor]})`).join(', '); return `Durante el período analizado, el producto más vendido fue ${top[claveNombre]} con un total de ${top[claveValor]}. Los demás productos incluyen: ${lista}. El total de ventas fue de ${total}, con un promedio de ${promedio.toFixed(2)} por producto.`; } export function generarInsightAutomático<T extends Record<string, any>>(datos: T[], claveNumerica: string, claveGrupo?: string): string { if (!datos.length) return 'No hay datos disponibles para generar insights.'; const valores = datos.map(d => d[claveNumerica]).filter(v => typeof v === 'number'); const total = valores.reduce((a, b) => a + b, 0); const promedio = total / valores.length; const max = Math.max(...valores); const min = Math.min(...valores); let mensaje = `Se analizaron ${valores.length} registros. El total acumulado es ${total}, con un promedio de ${promedio.toFixed(2)}. El valor máximo fue ${max} y el mínimo ${min}.`; if (claveGrupo) { const grupos = agruparPorClave(datos, claveGrupo); const grupoTop = Object.entries(grupos).sort((a, b) => { const sumaA = a[1].reduce((sum, item) => sum + item[claveNumerica], 0); const sumaB = b[1].reduce((sum, item) => sum + item[claveNumerica], 0); return sumaB - sumaA; })[0]; mensaje += ` El grupo con mayor contribución fue "${grupoTop[0]}" con ${grupoTop[1].length} registros.`; } if (max > promedio * 2) { mensaje += ` ⚠️ Se detectó un valor excepcionalmente alto que podría indicar un outlier o una anomalía.`; } return mensaje; }