4 votes

Quelle est la meilleure approche pour cloner les propriétés des objets lors de l'utilisation de map() ?

Je veux ajouter une nouvelle propriété (contactDetails.countryName) et attribuer une valeur à un objet imbriqué stocké dans un tableau appelé users en utilisant la fonction map().

J'ai récemment appris que je devais utiliser l'opérateur d'étalement (...) et ensuite créer/assigner la nouvelle propriété afin d'éviter de modifier mon tableau d'objets d'origine. J'ai donc développé deux implémentations différentes pour cela, mais je ne suis pas vraiment sûr de suivre les meilleures pratiques pour accomplir ce que je veux en ce qui concerne la sémantique et les performances.

À votre avis, quelle serait la meilleure approche pour accomplir ce que je veux faire ?

const countries = [
  { id: 3, countryName : "UK" },
  { id: 4, countryName : "Spain" },
  { id: 6, countryName : "Germany"}
];

const users = [
  { id : 1,
    name: "Douglas Camp",
    dateOfBirth: "23-06-1984",
    contactDetails:
      {
        country: 3,
        phone: "7373724997"
      }
  },
  {
    id : 2,
    name: "Martin Stein",
    dateOfBirth: "19-08-1992",
    contactDetails:
      {
        country: 6,
        phone: "3334343434"
      }
  },
];

const usersData = users.map(user=> {

// Version 1 : using spreading operator twice 

const newUser = {
    ...user,
    contactDetails: {
      ...user.contactDetails,
      countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
    }
  };  
  return newUser;
});

// Version 2: copying the original object property and using spread operator only for cloning the nested object properties

const newUser = {
    id: user.id,
    name: user.name,
    dateOfBirth: user.dateOfBirth,
    contactDetails: {
      ...user.contactDetails,
      countryName: countries.find(c=> c.id == user.contactDetails.country).countryName
    }
  };

console.log(users);
console.log(usersData);

1voto

Akrion Points 25

Voici une approche que vous pouvez envisager :

  • Tout d'abord, je voudrais Array.reduce les pays à un Carte vous pouvez donc les obtenir via key / value ou, dans ce cas, par countries.get(key) et éviter de filtrer ce tableau à chaque fois.

  • Vous pouvez parcourir les utilisateurs et créer un nouvel objet pour chacun d'eux. Dans ce cas, je les appelle accounts .

  • Vous pouvez également envisager d'utiliser Objet.assign

  • Notez que les deux ... opérateur et Object.assign son approches de clones peu profonds . Ils ne clonent pas récursivement les objets/enfants imbriqués. Pour cela, vous pouvez utiliser JSON.stringify y JSON.parse etc.

    let countries = [ { id: 3, countryName : "UK" }, { id: 4, countryName : "Spain" }, { id: 6, countryName : "Germany"} ].reduce((r,{id, countryName}) => (r.set(id, countryName), r), new Map()) // reduce with Map

    let users = [ { id : 1, name: "Douglas Camp", dateOfBirth: "23-06-1984", contactDetails: { country: 3, phone: "7373724997" } }, { id : 2, name: "Martin Stein", dateOfBirth: "19-08-1992", contactDetails: { country: 6, phone: "3334343434" } }, ];

    let accounts = users.map(user => Object.assign({}, user, { // <-- map through contactDetails: { ...user.contactDetails, countryName: countries.get(user.contactDetails.country) // <-- get by key } }))

    users[0].id = 2 // <-- modify users users[0].contactDetails.phone = "00000"

    console.log(users, accounts) // <-- no changes to accounts

Remarquez que lorsque nous mettons à jour le users[0].id y users[0].contactDetails.phone les valeurs des comptes n'ont pas été mises à jour.

0voto

Ryan Castner Points 333

J'utilise normalement la version 1, l'opérateur d'écartement deux fois. J'envisagerais également de vérifier immer qui vous permet d'effectuer des mises à jour mutables sur un brouillon cloné et se charge de le fusionner à nouveau pour vous.

const newUser = immer(user, draft => {
  draft.contactDetails.countryName = countries.find(
    c => c.id == user.contactDetails.country).countryName
  )
})

Il suffit d'éditer la propriété spécifique que vous voulez et les poignées d'immerger copiant le reste de la propriété.

0voto

ORBIT Points 1

Clonage et fusion de cartesSection Tout comme les tableaux, les cartes peuvent être clonées :

var original = new Map([
  [1, 'one']
]);

var clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false. Useful for shallow comparison

0voto

remoo Points 132

Personnellement, j'aime utiliser la version 1, car elle rend votre code beaucoup moins redondant et plus facile à lire. Elle transmet également toutes les propriétés de 'user' à newUser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X