Saltar al contenido principal

distinct

Paquete: @tiendana/utils

Elimina duplicados de un array. Opcionalmente puede eliminar duplicados basándose en una clave específica para arrays de objetos.

Características​

✅ Usa Set para performance óptima
✅ Soporte para arrays de primitivos
✅ Soporte para arrays de objetos con clave
✅ Type-safe con genéricos TypeScript
✅ No modifica el array original

Firma​

function distinct<T>(
array: T[],
key?: keyof T
): T[]

Parámetros​

ParámetroTipoDescripciónRequeridoDefault
arrayT[]Array del cual eliminar duplicados✅-
keykeyof TClave por la cual identificar duplicados (solo para objetos)❌-

Retorno​

Tipo: T[]

Nuevo array con elementos únicos, preservando el orden de primera aparición.

Ejemplos de Uso​

Array de Primitivos​

import { distinct } from '@tiendana/utils';

// Números
distinct([1, 2, 2, 3, 1, 4]);
// [1, 2, 3, 4]

// Strings
distinct(['apple', 'banana', 'apple', 'cherry']);
// ['apple', 'banana', 'cherry']

// Booleanos
distinct([true, false, true, true, false]);
// [true, false]

Array de Objetos sin Clave​

const items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 1, name: 'Item 1' } // referencia diferente
];

// Sin key, compara referencias de objeto
distinct(items);
// Retorna los 3 elementos (diferentes referencias)

Array de Objetos con Clave​

interface User {
id: number;
name: string;
email: string;
}

const users: User[] = [
{ id: 1, name: 'Ana', email: 'ana@example.com' },
{ id: 2, name: 'Juan', email: 'juan@example.com' },
{ id: 1, name: 'Ana García', email: 'ana.garcia@example.com' } // mismo id
];

// Eliminar por id
const uniqueUsers = distinct(users, 'id');
// [
// { id: 1, name: 'Ana', email: 'ana@example.com' },
// { id: 2, name: 'Juan', email: 'juan@example.com' }
// ]

// Eliminar por email
const uniqueByEmail = distinct(users, 'email');
// Retorna los 3 (emails diferentes)

En Filtros de Búsqueda​

const searchResults = [
{ id: 1, title: 'Result 1' },
{ id: 2, title: 'Result 2' },
{ id: 1, title: 'Result 1' }, // duplicado
{ id: 3, title: 'Result 3' }
];

const uniqueResults = distinct(searchResults, 'id');
// 3 resultados únicos

Tags Únicos​

const posts = [
{ title: 'Post 1', tags: ['javascript', 'react'] },
{ title: 'Post 2', tags: ['javascript', 'vue'] },
{ title: 'Post 3', tags: ['react', 'angular'] }
];

// Obtener todos los tags únicos
const allTags = posts.flatMap(post => post.tags);
const uniqueTags = distinct(allTags);
// ['javascript', 'react', 'vue', 'angular']

Combinar Arrays sin Duplicados​

const array1 = [1, 2, 3, 4];
const array2 = [3, 4, 5, 6];

const combined = distinct([...array1, ...array2]);
// [1, 2, 3, 4, 5, 6]

Con Datos de API​

interface Product {
sku: string;
name: string;
price: number;
}

async function fetchUniqueProducts() {
const [productsA, productsB] = await Promise.all([
fetch('/api/products/a').then(r => r.json()),
fetch('/api/products/b').then(r => r.json())
]);

// Combinar y eliminar duplicados por SKU
const allProducts: Product[] = [...productsA, ...productsB];
return distinct(allProducts, 'sku');
}

Casos de Uso Comunes​

  • Eliminar duplicados de listas: Tags, categorías, filtros
  • Combinar resultados: De múltiples APIs o fuentes de datos
  • Normalizar datos: Antes de procesar o mostrar
  • Filtros de búsqueda: Eliminar resultados repetidos
  • Selecciones de usuario: IDs de items seleccionados sin duplicar

Notas Técnicas​

  • Performance: O(n) - usa Set internamente para búsquedas rápidas
  • Orden: Preserva el orden de primera aparición de cada elemento
  • Referencias: Para objetos sin key, compara por referencia de memoria
  • Key undefined: Si el objeto no tiene la key especificada, se considera único
  • Inmutabilidad: No modifica el array original, retorna uno nuevo
  • Type narrowing: TypeScript infiere correctamente el tipo del array retornado

Implementación​

export function distinct<T>(array: T[], key?: keyof T): T[] {
const result: T[] = [];
const keysSet = new Set();

array.forEach(item => {
const value = key ? item[key] : item;
if (!keysSet.has(value)) {
keysSet.add(value);
result.push(item);
}
});

return result;
}

Ver También​