简体   繁体   中英

How to reduce this array of objects to this one?

I need to reduce an array of objects, the reduce function should count the number of repeated objects in the array and set the number as a value of quantity property in the repeated object.

const x = {a: 1, b: 3, quantity: 1};
const y = [{a: 2, b: 5}, {a: 0, b: 5}, x, {a: 10, b: 3}, x, x, {a: 4, b: 6}]

How to reduce y to equal:

[{a: 2, b: 5}, {a: 0, b: 5}, {a: 1, b: 3, quantity: 3}, {a: 4, b: 6}]

This is my attempt:

for (let i = 0; i < y.length; i++) {
       for (let j = i + 1; j < y.length; j++) {
         if (y[i] === y[j]) {
           y[i].quantity += 1;
           y[j] = null;
         }
       }
     }

Basically you need to check each property of the objects without quantity for getting a condensed result.

 var x = { a: 1, b: 3, quantity: 1 }, y = [{ a: 2, b: 5 }, { a: 0, b: 5 }, x, { a: 10, b: 3 }, x, x, { a: 4, b: 6 }], result = y.reduce((r, o) => { var keys = Object.keys(o); temp = r.find(q => Object.keys(q).length === keys.length && keys.every(k => k === 'quantity' || o[k] === q[k])); if (temp) { temp.quantity = (temp.quantity || 1 ) + 1; } else { r.push(o); } return r; }, []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Here is an easier approach, be careful not to mutate data.

Working example: https://stackblitz.com/edit/stackoverflow-transformation-3?file=index.js

const x = { a: 1, b: 3, quantity: 1 };
const y = [{  a: 2, b: 5 }, { a: 0, b: 5 }, x, { a: 10, b: 3 }, x, x, { a: 4, b: 6 }]

const output = y.reduce((acc, x, i) => {
  const index = acc.findIndex(y => y.hasOwnProperty('quantity'))
   // if the first obj with prop quantity is added
   // then just add the current value to the accumulator
  if (index > 0 && x.hasOwnProperty('quantity')) {
    acc[index] = {
      ...acc[index],
      quantity: acc[index]['quantity'] + x.quantity
    }
  }
  else {
    acc.push(x)
  }
  return acc;

}, [])

console.log('output', output)

UPDATE

Second approach, process of adding a product to the cart

// product which wants to be added to the cart
const selProduct = { id: 1, quantity: 1 };
// unique items by id in the car only
const cart = [
  { id: 0, quantity: 1 },
  { id: 2, quantity: 1 },
  { id: 3, quantity: 1 },
  { id: 1, quantity: 1 }
]
// check if selected product exists in the cart
const index = cart.findIndex(x => x.id === selProduct.id);
// if not, add it to the cart
if (index < 0) {
  cart.push(selProduct);
}
// if yes, increment the quantity of the already found product
else {
  cart[index] = {
    ...cart[index],
    'quantity': cart[index]['quantity'] + selProduct['quantity']
  }
}
console.log(cart)

You should never have multiple products with the same id in the cart and then preform the removal of duplicates...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM