Tengo una matriz de objetos (carrito de compras) y quiero eliminar los duplicados que tienen el mismo obj.id y obj.arr una matriz vacía. Después de eso, para aumentar obj.quantity en uno. Aquí está el arreglo original:
const cart = [ { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 2, "name": "pen", "arr": ["asa", "asd"], "quantity": 3 }, { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 3, "name": "ball pen", "arr": ["azx", "dcv"], "quantity": 1 } ]La salida esperada debería ser así:
const cart = [ { "id": 1, "name": "book", "arr": [], "quantity": 2 }, { "id": 2, "name": "pen", "arr": ["asa", "asd"], "quantity": 3 }, { "id": 3, "name": "ball pen", "arr": ["azx", "dcv"], "quantity": 1 } ] No sé cómo actualizar object.quantity después de eliminar el duplicado. Y si es posible, quiero mantener el elemento con el índice más pequeño.
¿Me podría ayudar?
Gracias
Código modificado de ¿Cómo eliminar todos los duplicados de una matriz de objetos? . en lugar de filter , utilicé reduce para luego encontrar y actualizar la cantidad del artículo duplicado
const cart = [ { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 2, "name": "pen", "arr": ["asa", "asd"], "quantity": 3 }, { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 3, "name": "ball pen", "arr": ["azx", "dcv"], "quantity": 1 } ] function findDupUpdateQty(arr){ return arr.reduce((acc, currentVal, index, self) => { if(index === self.findIndex((e)=> e.id === currentVal.id && e.arr.length === currentVal.arr.length)){ acc.push(currentVal) } else { //if there's a duplicate then update quanitity acc[acc.findIndex((e)=> e.id === currentVal.id && e.arr.length === currentVal.arr.length)].quantity += currentVal.quantity } return acc },[]) } console.log(findDupUpdateQty(cart))Ediciones con algunas de las sugerencias de @Corrl:
const cart = [ { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 2, "name": "pen", "arr": ["asa", "asd"], "quantity": 3 }, { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 3, "name": "ball pen", "arr": ["azx", "dcv"], "quantity": 1 } ] function findDupUpdateQty(arr){ return arr.reduce((acc, currentVal, index, self) => { //check if both arrays are the same let firstFoundIndex = self.findIndex((e)=> e.id === currentVal.id && JSON.stringify(e.arr) === JSON.stringify(currentVal.arr)) if(index === firstFoundIndex){ acc.push(currentVal) } else { self[firstFoundIndex].quantity += currentVal.quantity } return acc },[]) } console.log(findDupUpdateQty(cart))Para mantener el orden lo haría
const cart = [{ "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 2, "name": "pen", "arr": ["asa", "asd"], "quantity": 3 }, { "id": 1, "name": "book", "arr": [], "quantity": 1 }, { "id": 3, "name": "ball pen", "arr": ["azx", "dcv"], "quantity": 1 }] function removeDuplicates(cart) { let map = new Map() // groupBy id cart.forEach(obj => { let entry = map.has(obj.id) if (entry) { let value = map.get(obj.id) map.set(obj.id, [...value, obj]) } else { map.set(obj.id, [obj]) } }) map.forEach((value, key) => { // doubles? if (value.length > 1) { let allEmptyArrays = value.every(obj => obj.arr.length === 0) if (allEmptyArrays) { // keep only the first value let keepValue = value[0] // adjust quantity keepValue.quantity++ // overwrite existing entry map.set(key, [keepValue]) } } }) // rebuild cart return Array.from(map).map(([_, value]) => value[0]) } console.log(removeDuplicates(cart))¡Gracias a los dos!
Estaba planeando usar una de sus respuestas dentro del selector ( createSelector ) de la biblioteca 'reselect'. Pero parece que está incrementando obj.quantity , para todos los productos, no solo para aquellos con obj.arr una matriz vacía.
Así que investigué más y cambié mi addToCartReducer , según esta publicación . Ahora toda la acción ocurre dentro del reductor, no dentro del selector. Cada vez que agrego al carrito un producto con obj.arr una matriz vacía, incrementa su quantity en 1.