Convertir un array en un objeto con reduce

8 ene. 2021
·
  • JavaScript
·
  • programación funcional
  • reduce

El método reduce es muy polivalente en JS. El típico caso de uso es el de sumar un array, es decir, reducir un array a un solo valor pero también ofrece multitud de otras posibilidades y es muy recomendable aprender a usarlo porque evita muchos dolores de cabeza.

Vamos a imaginar un array así:

const books = [
  { id: 1000, title: 'La Insoportabilidad de Leer Esto', year: 1981 },
  { id: 2000, title: 'La Conjura de los Recios', year: 1978 },
  { id: 3000, title: 'El Señor de los Ruidillos', year: 2008 },
  { id: 4000, title: 'El Almuerzo Vestido', year: 2001 },
];

Queremos convertirlo en un objeto indexado por el id de cada libro y que termine quedando así:

const books = {
  1000: { id: 1000, title: 'La Insoportabilidad de Leer Esto', year: 1981 },
  2000: { id: 2000, title: 'La Conjura de los Recios', year: 1978 },
  3000: { id: 3000, title: 'El Señor de los Ruidillos', year: 2008 },
  4000: { id: 4000, title: 'El Almuerzo Vestido', year: 2001 },
};

Con reduce es bastante sencillo en realidad:

const initialValue = {};
const reducer = function( accumulator, element, index ) {
  return {
    ...accumulator,
    [ element.id ]: element
  }
}
const result = books.reduce( reducer, initialValue );

Por cada elemento del array, reduce ejecuta la función que le pasamos como parámetro, reducer. Éste recibe primero el acumulador que no es más que el resultado que se va acumulando durante cada iteración. reduce además, recibe como segundo parámetro un valor inicial de tal forma que en la primera iteración, el valor del acumulador será ese valor inicial e irá cambiando con cada iteración.

El reducer lo que hace es devolver el acumulador con un elemento más, quedando finalmente un objeto cuyos índices son los id de cada libro.

Para simplificar, yo suelo escribirlo así:

const result = books.reduce( ( accumulator, element, index ) => ( {
  ...accumulator,
  [ element.id ]: element
} ), {} );

Una vez que te acostumbras a comprimir JS de esta manera, no quieres abandonarlo.