2017-10-17 2 views
0

je travaille sur un projet où j'ai 2 tableaux d'objets et les éléments suivants sont les différents cas, les données peuvent être en.tableaux d'objets Manipulation des données uniques

// Case 1 
var arr1=[{id:1,quantity:10}] 
var arr2=[{id:1,quantity:10},{id:2,quantity:20}] 

// Case 2 
var arr1=[] 
var arr2=[{id:1,quantity:10},{id:2,quantity:20}] 

// Case 3 
var arr1=[{id:1,quantity:12}] 
var arr2=[{id:1,quantity:10},{id:2,quantity:20}] 

// Case 4 
var arr1=[{id:1,quantity:10},{id:1,quantity:20}] 
var arr2=[{id:1,quantity:10}] 

Ainsi, le array1 pourrait être empty, peut avoir l'un des objets de array2 ou les deux objets de array2 avec une valeur de quantité différente. Je voudrais mettre à jour le tableau principal ou arr1 basé sur arr2 mais ne veut pas glisser complètement arr1 avec arr2 avec le type de solution arr1 = arr2. arr1 devrait mettre à jour la quantité basée sur arr2 et ajouter ou enlever basé sur la même chose.

+0

Pouvez-vous donner un avant/après exemple? –

+0

Comment le code peut-il mettre à jour et ajouter et supprimer des éléments en même temps? – guest271314

+0

Pouvez-vous expliquer comment le résultat serait différent de 'arr1 = arr2'? – trincot

Répondre

1

Si arr1 = arr2 serait une solution, sauf que vous voulez muterarr1 au lieu de remplacer, puis envisager d'utiliser splice:

var arr1=[{id:0,quantity:1},{id:2,quantity:12},{id:3,quantity:9}], 
 
    arr2=[{id:1,quantity:10},{id:2,quantity:20}]; 
 

 
arr1.splice(0, arr1.length, ...arr2); 
 

 
console.log(arr1);

Si votre préoccupation est que les objets arr1 ne doivent pas être remplacé lorsque leur id existe dans arr2, mais être mutées (en gardant leurs références), je dirais:

var arr1=[{id:0,quantity:1},{id:2,quantity:12},{id:3,quantity:9}], 
 
    arr2=[{id:1,quantity:10},{id:2,quantity:20}]; 
 
// key both arrays by id in Maps 
 
var mp1 = new Map(arr1.map(obj => [obj.id, obj])), 
 
    mp2 = new Map(arr2.map(obj => [obj.id, obj])); 
 
// traverse arr1 from right to left so deletions will not affect the loop 
 
arr1.reduceRight((_, obj, i) => { 
 
    if (mp2.has(obj.id)) { 
 
     Object.assign(obj, mp2.get(obj.id)); // update 
 
    } else { 
 
     arr1.splice(i, 1); // delete 
 
    } 
 
}, null); 
 
arr2.forEach((obj) => { 
 
    if (!mp1.has(obj.id)) { 
 
     arr1.push(obj); // insert 
 
     // If you need the inserted object to be a copy, then do: 
 
     // arr1.push(Object.assign({}, obj)); 
 
    } 
 
}); 
 

 
// If you need the result to be sorted by `id`, then do this also: 
 
arr1.sort((a,b) => a.id - b.id); 
 

 
console.log(arr1);

+0

J'ai essayé cette approche mais puisque cela ajoute tout de array2 à array1 et puisque j'utilise cette logique en angulaire pour angulaire- animer et cela anime tous les ajouts au lieu d'une seule addition. Je veux seulement un ajout pour avoir l'effet d'animation et pas tout, donc posé cette question ici, sinon une simple recherche google l'aurait résolu. Merci cependant – DevX136

+0

J'ai ajouté une 2ème solution qui garde les références d'objets dans 'arr1' intacte quand leur' id' existe dans 'arr2'. – trincot

+0

Cela semble correct et pourrait fonctionner, va le tester une fois que je suis à la maison. – DevX136

1
for(const el of arr2){ 
const dupe = arr1.find(e => e.id === el.id); 
if(dupe){ 
    dupe.quantity = el.quantity; 
}else{ 
    arr1.push(el); 
} 
} 

Mais en réalité, une carte (id -> quantité) serait la meilleure structure de données ici (ou un objet):

const els = new Map(arr1.map(el => [el.id, el.quantity])); 
//to add 
arr2.forEach(el => els.set(el.id, el.quantity + (els.get(el.id) ||0)); 
+1

Dans la 2ème solution - ajoutez un '(els.get (el.id) || 0) par défaut' ou vous obtiendrez un 'NaN' s'il ne s'agit pas d'un doublon. –

+0

bonne solution mais si l'arr2 a moins d'éléments que arr1 alors arr1 ne change pas en arr2. – DevX136

+0

@ devX136 non il ne devrait pas ... –