0

I am pretty new to JS high array methods and I have an array of objects that contain cost categories and value like this:

[{category: "Bars", amount: 31231},
{category: "Transport", amount: 1297},
{category: "Utilities", amount: 12300},
{category: "Bars", amount: 2000},
{category: "Transport", amount: 2500},
{category: "Education", amount: 21321}]

My goal is to reduce this array and sum the 'amount' values like this:

[{category: "Bars", amount: 33231},  //31231+2000
{category: "Transport", amount: 3797}, //1297+2500
{category: "Utilities", amount: 12300},
{category: "Education", amount: 21321}]

I tried reduce() and and forEach(), but I could not really find a way to solve the issue. Thank you!

2
  • 1
    "i tried ..." please add this. Commented Oct 18, 2018 at 20:51
  • You can iterate thru the array and when categorys match add the amount to the first object and delete the latest one you found. Commented Oct 18, 2018 at 20:57

5 Answers 5

3

You should use reduce method to do it, so you will iterate over the array with items and for each item you will ask if that category don't exist into the newObject then initialize it with 0 value and then sum up the amount.

var objects = [{category: "Bars", amount: 31231},
{category: "Transport", amount: 1297},
{category: "Utilities", amount: 12300},
{category: "Bars", amount: 2000},
{category: "Transport", amount: 2500},
{category: "Education", amount: 21321}];

var newObjectsMerged = objects.reduce((object, item) => {
  var category = item.category;
  var amount = item.amount;
  if (!object.hasOwnProperty(category)) {
    object[category] = 0;
  }
  
  object[category] += amount;
  return object;
}, {});

console.log("newObjectsMerged", newObjectsMerged);

Sign up to request clarification or add additional context in comments.

1 Comment

Great and easy to follow solution! Thank you!
2

You could reduce the array by taking finc for the object and update or add a new array to the result set.

var array = [{ category: "Bars", amount: 31231 }, { category: "Transport", amount: 1297 }, { category: "Utilities", amount: 12300 }, { category: "Bars", amount: 2000 }, { category: "Transport", amount: 2500 }, { category: "Education", amount: 21321 }],
    result = array.reduce((r, { category, amount }) => {
        var temp = r.find(o => o.category === category);
        if (temp) {
            temp.amount += amount;
        } else {
            r.push({ category, amount });
        }
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

var items = [{category: "Bars", amount: 31231},
{category: "Transport", amount: 1297},
{category: "Utilities", amount: 12300},
{category: "Bars", amount: 2000},
{category: "Transport", amount: 2500},
{category: "Education", amount: 21321}];


var itemsByName = items.reduce(function (map, item) {
  
  var summarizedItem = map.get(item.category);
  if (!summarizedItem) {
    summarizedItem = item;
  } else {
    summarizedItem.amount += item.amount;
  }
  
  map.set(item.category, summarizedItem);
  
  return map;
}, new Map());

console.log(Array.from(itemsByName.values()))

Comments

0

Try this:

var items = [{category: "Bars", amount: 31231},
{category: "Transport", amount: 1297},
{category: "Utilities", amount: 12300},
{category: "Bars", amount: 2000},
{category: "Transport", amount: 2500},
{category: "Education", amount: 21321}];

// get all categories names
var categories = items.map(item => item.category).filter((value, index, self) => self.indexOf(value) === index);

// create a new object with sum of amounts
var result = categories.map(item => { 
  return { 
     category: item, 
     amount: items.filter(c => c.category === item).reduce((accum, curr) => accum + curr.amount, 0) 
  } 
});

Comments

0

A short ES6 version with Array.prototype.reduce and Object.keys:

const data = [{category: "Bars", amount: 31231},{category: "Transport", amount: 1297},{category: "Utilities", amount: 12300},{category: "Bars", amount: 2000},{category: "Transport", amount: 2500},{category: "Education", amount: 21321}];

const grouped = data.reduce((all, {category: c, amount: a}) =>
    ({...all, [c]: (all[c] || 0) + a }), {});

const result = Object.keys(grouped).map(k => ({category: k,amount: grouped[k] }));

console.log(result);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.