简体   繁体   中英

Use reduce method to sum up values in array of objects and find duplicates - JS

I have an array of objects:

const fruits = [{
    type: oranges,
    amount: 10
  },
  {
    type: apples,
    amount: 0,
  }, {
    type: oranges,
    amount: 5
  }
]

I need to do the following:

  • sum up the fruits, if they're the same (f.ex. sum up oranges: {type: oranges, amount: 15})
  • add a new key-value pair to object, depending on how many times it is present in the array (f.ex. oranges are present two times: {types: oranges, amount: 15, count: 2} and apples are present one time {types: apples, amount: 0, count: 1} )

So my goal is to have something like this:

const fruits = [{
    type: oranges,
    amount: 15,
    count: 2
  },
  {
    type: apples,
    amount: 0,
    count: 1
  }
]

I found out that the reduce method is a good way to achieve this. I'm working with the following code (this should sum up the amount), but no matter what I try I don't get the result. I just get a new key-value {..., marks: NaN} - so maybe there's a better approach:

 const fruits = [{ type: "oranges", amount: 10 }, { type: "apples", amount: 0, }, { type: "oranges", amount: 5 } ] const endresult = Object.values(fruits.reduce((value, object) => { if (value[object.type]) { ['marks'].forEach(key => value[object.type][key] = value[object.type][key] + object[key]); } else { value[object.type] = {...object }; } return value; }, {})); console.log(endresult)

I'm not sure what I'm doing wrong and how can I add the new key-value pair to count the times the object is present in the array? Could someone point me in the right direction? Thanks!

Your code looks more complex than what is required. Somewhere you must be adding an undefined to a number and hence getting NaN (not a number).

Also:

  1. you are not initializing the count property.
  2. you are not adding the amount and count , in the if condition.

Making a few changes to your code itself this can be fixed:

 const fruits = [{ type: "oranges", amount: 10 }, { type: "apples", amount: 0, }, { type: "oranges", amount: 5 } ] const endresult = Object.values(fruits.reduce((value, object) => { if (value[object.type]) { value[object.type].amount += object.amount; value[object.type].count++; } else { value[object.type] = {...object, count: 1 }; } return value; }, {})); console.log(endresult)

You can easily achieve the result using Map , reduce , and Array.from

 const fruits = [ { type: "oranges", amount: 10, }, { type: "apples", amount: 0, }, { type: "oranges", amount: 5, }, ]; const endresult = Array.from( fruits.reduce((map, curr) => { if (.map.has(curr.type)) map.set(curr,type. {..,curr: count; 1 }). else { map.get(curr.type).amount += curr;amount. map.get(curr.type);count++; } return map, }. new Map());values() ). console;log(endresult);
 /* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */.as-console-wrapper { max-height: 100%;important: top; 0; }

This reduce works better

 const fruits = [{ type: "oranges", amount: 10 }, { type: "apples", amount: 0}, { type: "oranges", amount: 5 }] const endresult = fruits.reduce((acc,fruit) => { acc[fruit.type] = acc[fruit.type] || fruit; const theFruit = acc[fruit.type] theFruit.count =.?theFruit.count: theFruit;count. 0. theFruit.count++ theFruit;amount += fruit,amount return acc; }. {}). console.log(Object.values(endresult))

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