Map + array de IDs para acelerar búsquedas

Clase 23 de 24Curso de Manipulación Avanzada de Datos con JavaScript

Resumen

Adopta una estrategia clara para acelerar búsquedas y simplificar el CRUD en JavaScript: usar Map en lugar de array dentro de un repositorio basado en localStorage. Este enfoque prioriza consultas instantáneas, reduce código repetitivo y, con un array de IDs, conserva el orden para features como drag and drop.

¿Por qué cambiar de array a map en localStorage?

Usar map acelera las búsquedas y simplifica la lógica. Un array obliga a hacer find, findIndex o recorrer posiciones. Con map, un set agrega o actualiza, get recupera al instante y delete elimina sin calcular índices. Sin embargo, para la persistencia en localStorage, hay que transformar el map a array para serializarlo, y rehidratarlo luego en memoria.

  • Ventaja clave: consultas O(1) con get y has.
  • Persistencia: serializar con un array y deserializar reconstruyendo el map.
  • Sin duplicados: map evita claves repetidas por naturaleza.
  • Trade-off: se pierde el orden del array; se recupera con un array de IDs.

¿Cómo se serializa y rehidrata el map?

  • Guardar en localStorage como array de values del map.
  • Al recargar, rehidratar: recorrer el array y hacer set(id, entidad) en el map.
// Guardar (saveStorage) const saveStorage = () => { const payload = Array.from(habitsMap.values()); localStorage.setItem('habits', JSON.stringify(payload)); }; // Cargar (rehidratar) const habitsMap = new Map(); const saved = JSON.parse(localStorage.getItem('habits') ?? '[]'); saved.forEach(habit => { habitsMap.set(habit.id, habit); });

¿Cómo se simplifica el CRUD con map?

  • Crear/actualizar: set(id, entidad) actualiza o inserta.
  • Leer: get(id) retorna la entidad o null/undefined.
  • Verificar existencia: has(id).
  • Eliminar: delete(id). Sin cálculos de posición.
  • Limpiar todo: clear().
// Create/Update habitsMap.set(habit.id, habit); saveStorage(); // Read const habit = habitsMap.get(id) ?? null; // Delete if (habitsMap.has(id)) { habitsMap.delete(id); saveStorage(); }

¿Cómo mantener el orden y soportar reordenamiento?

Como map no garantiza orden, un array de IDs conserva posiciones para listar, filtrar y reordenar. Este patrón permite features como drag and drop sin perder la velocidad del map.

  • Mantén solo IDs en un array, no objetos.
  • Al crear: push(id) para registrar la posición.
  • Al eliminar: filter para sacar el id.
  • Al listar: recorre orderIds y resuelve con map.get(id).
// Estado adicional para el orden let orderIds = []; // Crear habitsMap.set(habit.id, habit); orderIds.push(habit.id); saveStorage(); // Eliminar if (habitsMap.delete(id)) { orderIds = orderIds.filter(x => x !== id); saveStorage(); } // Listar (ordenado) const list = orderIds .map(id => habitsMap.get(id)) .filter(Boolean);

¿Qué implica en list, filtros y map?

  • list ahora parte de orderIds para respetar posiciones.

  • Puedes reordenar moviendo IDs dentro de orderIds.

  • Luego aplicas filter, map o reduce sobre el array resultante.

  • Ventaja: orden estable y consultas rápidas.

  • Costo: sincronizar orderIds en create/delete y reordenamientos.

¿Cuándo usar map y cuándo es sobre ingeniería?

La técnica map + array de IDs es potente, pero su valor aparece con volúmenes grandes. Con pocos datos (menos de ~200), el beneficio puede ser imperceptible y añadir complejidad innecesaria. En contextos con muchísimos eventos o métricas, lo adecuado suele ser una base de datos con indexamiento o de series de tiempo.

  • Úsalo si manejas datos intensivos en frontend tipo dashboards con muchas interacciones.
  • En casos pequeños (hábitos de usuario): puede ser sobre ingeniería.
  • Para grandes volúmenes: opciones como ClickHouse o TigerData están pensadas para consultas rápidas y análisis de eventos o finanzas.
  • En manejo de estado, verás el patrón map + array de IDs en librerías como Redux o NgRx.

¿Te gustaría comentar cómo mantienes el orden y la persistencia en tus listas, o qué patrón usas para acelerar búsquedas en producción?