Unisci due array e modificali in posizione (javascript) [duplicato]
Ho due array di oggetti, originali e selezionati, come questo:
original =[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 2 },{ id: 76 , quantity: 2 }]
selected = [{ id: 2 , quantity: 1 }, { id: 100 , quantity: 7 }]
Voglio essere in grado di unire quegli array su id e se hanno un id simile dovrei riassumere la quantità,
L'array risultante, in questo caso, dovrebbe essere simile a questo:
result=[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 3 },{ id: 76 , quantity: 2 } , { id: 100 , quantity: 7 }]
Ho pensato di fare qualcosa del genere:
const result =original.map(o => ({
...selectedArray.findIndex((s) => {(s.id === o.id) && selected)? return }
...original
}));
Ma non sono sicuro di come dovrei aggiungere alla quantità, qualsiasi aiuto o risorsa da esaminare sarebbe apprezzato.
Risposte
Potresti trovare l'oggetto e aggiornare quantityo spingere un nuovo oggetto.
const
original = [{ id: 4, quantity: 4 }, { id: 2, quantity: 2 }, { id: 76, quantity: 2 }],
selected = [{ id: 2, quantity: 1 }, { id: 100, quantity: 7 }],
merged = [...original, ...selected].reduce((r, { id, quantity }) => {
const item = r.find(q => q.id === id);
if (item) item.quantity += quantity;
else r.push({ id, quantity });
return r;
}, []);
console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Una soluzione con una tabella hash.
const
mergeTo = (target, reference = {}) => ({ id, quantity }) => {
if (reference[id]) reference[id].quantity += quantity;
else target.push(reference[id] = { id, quantity });
},
original = [{ id: 4, quantity: 4 }, { id: 2, quantity: 2 }, { id: 76, quantity: 2 }],
selected = [{ id: 2, quantity: 1 }, { id: 100, quantity: 7 }],
merged = [],
merge = mergeTo(merged);
original.forEach(merge);
selected.forEach(merge);
console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Non penso che questo non sia un buon metodo, ma penso che funzionerà.
selected.forEach(obj => {
var exists = original.find(x => x.id === obj.id);
if(exists) {
exists.quantity += obj.quantity;
} else {
original.push(obj);
}
});
console.log(original);
Ecco una soluzione ottimale semplice da capire che funziona nel O(n+m)tempo. Dovresti usarlo se le dimensioni dell'array sono grandi. Dove ne msono le lunghezze di array originale selected.
let original =[{ id: 4 , quantity: 4 },{ id: 2 , quantity: 2 },{ id: 76 , quantity: 2 }];
let selected = [{ id: 2 , quantity: 1 }, { id: 100 , quantity: 7 }];
let obj = Object.fromEntries(original.map(e => [e.id, e]));
selected.forEach(e => {
if (obj[e.id]) {
obj[e.id].quantity += e.quantity;
} else {
obj[e.id] = e;
}
});
let result = Object.values(obj);
console.log(result);