Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

122
Vistas
Mapping an array of objects only works on a copy of the array

I have the feeling that this is an obscure side of Javascript that I simply do not know or understand.

I'm retrieving an array of objects from a database using Sequelize. It's a relatively complex array, as in contains associations. The array looks like this (it is simplified) :

[
  {
    name: '...',
    director: '...',
    genres: [
      {id: 1, name: 'Mystery'},
      {id: 2, name: 'Thriller'},
    ],
  },
  ...
]

I want to map this array so to change the format of genres from this:

genres: [
  {id: 1, name: 'Mystery'},
  {id: 2, name: 'Thriller'},
],

to this:

genres: ['Mystery', 'Thriller'],

So I did something which I believe is quite common in Javascript :

movies.map((movie) => {
  movie.genres = movie.genres.map(g => g.name);
  movie.actors = movie.actors.map(a => a.name);
  return movie;
});
console.log(JSON.stringify(movies));

However, once printed to the console, the array is completely unchanged. To have the desired effect on this array, I had to convert it into a string of characters and back into an array before performing the map() operations, like so:

movies = JSON.parse(JSON.stringify(movies));
movies.map((movie) => {
  movie.genres = movie.genres.map(g => g.name);
  movie.actors = movie.actors.map(a => a.name);
  return movie;
});
console.log(JSON.stringify(movies));

Why did it work ? I'm guessing that doing this conversion back and forth removed certain fields from the object, but I do not see how this could've had an effect on the array.

EDIT: using other methods like Array.from or the spread operator (movies = [...movies]) does not work.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

I am not familiar with Sequelize, but my best guess is that when you run JSON.parse and JSON.stringify, you create a copy of the value returned from Sequelize. When you create a copy, your code then "owns" the new object, thus allowing changes to be applied.

about 4 years ago · Juan Pablo Isaza Denunciar

0

If your optionsArray argument includes the 'IMMUTABLE' option then it's working as designed.

If you want to check it (not to solve anything but just to feel a little more sane) then you can probably verify immutability by seeing what Object.getOwnPropertyDescriptor(movies, 'genres') returns.

In which case, yes, creating a copy of the object is best. If you ascribe to functional programming, it's the "right" way to do it. Never changing objects but instead returning new ones is a fundamental practice of functional programming and avoids entire categories of programming errors.

sean-777 is right, you can clone it using several different libraries, or structuredClone(). In the case of your example, I'd probably just go with

function getName({name}) { return name; }
function mapName(a) {
  a.map(getName);
}
function convertMovie(movie) {
  return {
    ...movie,
    genres: mapName(movie.genres),
    actors: mapName(movie.actors)
  };
}
function convertMovies(movies) {
  return movies.map(convertMovie)
}
const moviesConverted = convertMovies(movies);
console.log(JSON.stringify(moviesConverted));
about 4 years ago · Juan Pablo Isaza Denunciar

0

You can use structuredClone() method which creates a deep clone of a given value using the structured clone algorithm.

Demo :

const jsObj = [
  {
    name: 'alpha',
    director: 'beta',
    genres: [
      {id: 1, name: 'Mystery'},
      {id: 2, name: 'Thriller'},
    ],
  }
];

const clonedObj = structuredClone(jsObj);

const modifiedObj = clonedObj.map(obj => {
    obj.genres = obj.genres.map(genreObj => genreObj.name)
  return obj;
});

console.log(jsObj);
console.log(modifiedObj);

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda