0
votes

Comment puis-je répandre correctement 2 tableaux écraser les anciennes valeurs correspondant à l'identifiant d'objet

Mon objectif est de combiner les valeurs des deux tableaux, écrasant les objets correspondant à tous les IDID. Est-ce possible?

[
    { _id: 1, label: 'a' },
    { _id: 2, label: 'b' }, 
    { _id: 3, label: 'c' },
    { _id: 2, label: 'updated b' }, 
    { _id: 3, label: 'updated c' }
]


3 commentaires

La propagation n'est pas destinée à le faire (pas dans la façon dont vous l'utilisez, au moins). Autre que cela, vous avez des références d'objet différentes. La meilleure solution serait donc de construire la nouvelle matrice en agrégeant les deux tableaux en considérant _id comme clé.


Etant donné que le _id n'est qu'un attribut de l'élément et non l'élément lui-même, vous ne pouvez pas le faire par une simple diffusion mais aurait plutôt besoin d'une autre ou d'une autre itération.


L'ordre final des éléments comporte-t-il?


6 Réponses :


2
votes

Vous devez noter que la syntaxe de diffusion ne peut pas en soi d'objets remplailleurs avec une clé spécifique, vous devez le faire vous-même.

Vous pouvez utiliser array.pototype.reduce code> et grouper l'objet basé sur l'objet sur _ID et écraser des objets avec le même ID. p>

p>

var oldState = [
               { _id: 1, label: 'a' },
               { _id: 2, label: 'b' }, 
               { _id: 3, label: 'c' }
           ]

var newState = [
               { _id: 2, label: 'updated b' },
               { _id: 3, label: 'updated c' }
           ]
           
const res = oldState.concat(newState).reduce((acc, item) => {
   acc[item._id] = {...(acc[item._id] || {}), ...item};
   return acc;
}, {})

const sol = Object.values(res);
console.log(sol);


0 commentaires

1
votes

Vous pouvez créer un Plan à partir de votre Newstate code> avec les touches étant l'identifiant d'objet et les valeurs étant les objets eux-mêmes. Ensuite, vous pouvez mapper votre oldstate code> et remplacer tous les objets anciens avec les nouveaux objets dans la carte si son identifiant existe:

p>

const oldState = [{ _id: 1, label: 'a' }, { _id: 2, label: 'b' }, { _id: 3, label: 'c' } ];
const newState = [{ _id: 2, label: 'updated b' }, { _id: 3, label: 'updated c' } ];

const newStateMap = new Map(newState.map(o => [o._id, o]));
const res = oldState.map(o => newStateMap.get(o._id) || o);
console.log(res);


0 commentaires

1
votes

Je réduisais tous les articles à un objet, puis obtenez les valeurs de l'objet:

p>

const oldState = [
  { _id: 1, label: 'a' },
  { _id: 2, label: 'b' }, 
  { _id: 3, label: 'c' }
];

const newState = [
  { _id: 2, label: 'updated b' },
  { _id: 3, label: 'updated c' }
];

const merge = (oldState, newState) => Object.values(
  [...oldState, ...newState].reduce((a, v) => (a[v._id] = v, a), {})
);

console.log(merge(oldState, newState));


1 commentaires

Utilisation intelligente de objet.values ​​ ici.



0
votes

Vous pouvez construire des objets et la désigner dans un nouvel objet et GE les valeurs de celui-ci.

p>

const
    getObject = (array, key) => Object.fromEntries(array.map(o => [o[key], o])),
    oldState = [{ _id: 1, label: 'a' }, { _id: 2, label: 'b' }, { _id: 3, label: 'c' }],
    newState = [{ _id: 2, label: 'updated b' }, { _id: 3, label: 'updated c' }],
    result = Object.values({
        ...getObject(oldState, '_id'),
        ...getObject(newState, '_id')
    });

console.log(result);


0 commentaires

2
votes

J'utiliserais array.reduce () code> avec une carte comme accumulateur. Le code est un peu propre, et la carte conserve également l'ordre d'origine des éléments (un objet les commanderait par la valeur numérique de _id code>):

p>

const oldState = [{"_id":1,"label":"a"},{"_id":2,"label":"b"},{"_id":3,"label":"c"}]
const newState = [{"_id":2,"label":"updated b"},{"_id":3,"label":"updated c"}]
           
const result = Array.from(
  [...oldState, ...newState]
    .reduce((acc, item) => acc.set(item._id, item), new Map())
    .values()
)

console.log(result);


1 commentaires

Solution intéressante, je ne pensais pas à s'appuyer sur des cartes, même si c'est vraiment un moyen intelligent de résoudre le problème.



0
votes

Il est possible de créer un objet qui contiendra des éléments uniques, puis utilisez la méthode mapper code> pour créer un objet fusionné:

p>

const oldState = [
  { _id: 1, label: 'a' },
  { _id: 2, label: 'b' },
  { _id: 3, label: 'c' }
];

const newState = [
  { _id: 2, label: 'updated b' },
  { _id: 3, label: 'updated c' }
];

const mapping = new Map(newState.map(s => [s._id, s]))
const result = oldState.map((s, i)=> ({ ...mapping.get(s._id) || s}));
console.log(result);


0 commentaires