Alguna vez han querido limpiar los elementos distintos de un arreglo en javascript? O obtener los objetos distintos un arreglo a través de sus propiedades? Bien en este post explicamos varias maneras practicas de lograrlo.

De elementos primitivos

Los valores primitivos en JavaScript son inmutables excepto el tipo Object. Los valores primitivos en javascript son:

  • null
  • undefined
  • Number
  • String
  • Symbol

Entonces los arreglos de valores primitivos pueden ser usados como opciones de selección en las cuales no queremos valores duplicados. Por ejemplo digamos que tenemos un registro directo de la base de datos con todos los años que han sido ingresados: [2016, 2017, 2017, 2016, 2019, 2018, 2019] y queremos que se seleccione uno de los que hay disponibles en los registros. El arreglo resultante sería: [2016, 2017, 2018, 2019] para que de ese modo se pueda seleccionar fácilmente uno de los años. En ese escenario necesitamos limpiar los duplicados del arreglo original.

Hay dos formas comunes de hacerlo (en ES5 y ES6 respectivamente) obteniendo los valores únicos de un arreglo de primitivos. Básicamente, primero se define un callback para revisar si el valor ocurre en un arreglo original, y luego filtrarlo para que solo las opciones que ocurren por primera vez se mantengan.

const distinto = (valor, indice, self) => {
    return self.indexOf(valor) === indice;
}

const años = [2016, 2017, 2017, 2016, 2019, 2018, 2019];
años.filter(distinto);

> (4) [2016, 2017, 2019, 2018]

Las cosas se simplifican mucho cuando utilizamos ES6 y los operadores de propagación (…) junto con el tipo Set. Un Set es una estructura de datos que no permite que existan duplicados en su contenido, entonces si pasamos el array a un set y luego a un array otra vez… Bingo! Estas 3 operaciones se logran en una sola linea:

const años = [2016, 2017, 2017, 2016, 2019, 2018, 2019];
const distintos = [...new Set(años)]

> (4) [2016, 2017, 2019, 2018]

Con esta solución debemos ser cuidadosos porque solo funciona con valores primitivos. Si tenemos, por ejemplo, un arreglo de fechas, entonces necesitaremos algunos métodos personalizados. Digamos que tenemos un arreglo de fechas:

const fechas = [
    new Date(2018, 8, 1),
    new Date(2018, 9, 1),
    new Date(2018, 8, 1),
    new Date(2018, 9, 1),
];

Y hacemos el hechizo de el operador de propagación, no funcionara con las fechas porque la clase Set compara objetos por referencia.

[...new Set(fechas)];


> 0: Sat Sep 01 2018 00:00:00 GMT-0600 (CST) {}
> 1: Mon Oct 01 2018 00:00:00 GMT-0600 (CST) {}
> 2: Sat Sep 01 2018 00:00:00 GMT-0600 (CST) {}
> 3: Mon Oct 01 2018 00:00:00 GMT-0600 (CST) {}

De objetos y propiedades

Muy a menudo, estamos tratando con objetos JSON que vienen de una base de datos. Ahora queremos obtener valores distintos de un arreglo de objetos. El arreglo es:

[ 
    {"nombre":"Juan",       "edad":17 }, 
    {"nombre":"Roberto",    "edad":17 }, 
    {"nombre":"Tomas",      "edad":35 } 
]

Y si queremos obtener solo las edades distintas del arreglo (de nuevo para filtrar entre las personas por edad), la solución, aunque pareciera que no, es realmente fácil. Primero mapeamos el arreglo a un nuevo arreglo que solo contenga valores primitivos.

const edadesDistintas = [... new Set(edades.map(x => x.age))];

> (2) [17, 35]

Vamos a complicarla un poco mas, digamos que tenemos como resultado de la base de datos un conjunto de registros de los departamentos de la universidad:

[
  { id: 3, nombre: 'Registro Y Estadistica', añoFiscal: 2018 },
  { id: 5, nombre: 'Escuela Tecnica', añoFiscal: 2018 },
  { id: 3, nombre: 'Registro Y Estadistica', añoFiscal: 2017 },
  { id: 5, nombre: 'Escuela Tecnica', añoFiscal: 2017 }
]

A veces queremos obtener un arreglo de objetos a través de los valores de sus propiedades, Por ejemplo: para cada objeto el id y el nombre son relaciones 1:1.

Queremos obtener objetos que tienen el mismo id y nombre para poblar una selección de departamentos, por lo tanto necesitamos que las llaves tengan in formato “id-nombre” y filtrar las repetidas.

Entonces necesitamos 2 pasos: Primero, generamos un arreglo de los id distintos. Después mapeamos el arreglo de id y prácticamente creamos un nuevo arreglo sin repetidos a partir del Set:

const resultado = Array.from(new Set(datos.map(s => s.id)))
    .map(id => {
        return {
            id: id,
            nombre: datos.find(s => s.id === id).name
        };
    });

resultado
[
  { id: 3, nombre: 'Registro Y Estadistica', añoFiscal: 2018 },
  { id: 5, nombre: 'Escuela Tecnica', añoFiscal: 2018 },
]

 

Categorized in: