Milos
Milos

Reputation: 619

How to group array of objects by value of object and sum the result in new property

I have an array of objects like this

const orders = [{
    "oreder": "Order/1",
    "itemCount": 2    
  }, {
    "oreder": "Order/2",
    "itemCount": 1
  }, {
    "oreder": "Order/3",
    "itemCount": 3
  }, {
    "oreder": "Order/4",
    "itemCount": 2
  }, {
    "oreder": "Order/5",
    "itemCount": 2
  }, {
    "oreder": "Order/6",
    "itemCount": 1
 }];

and what I'm trying to achieve is to group objects by itemCount and ad new property to each object with the name numberOfOrders and value which would be the sum of the same itemCount properties. Here's an example of what I want

const orders = [{
    "itemCount": 1,
    "numberOfOrders": 2,
  }, {
    "itemCount": 2,
    "numberOfOrders": 3,
  }, {
    "itemCount": 3,
    "numberOfOrders": 1,
 }];

I've tried to achieve this by using reduce

const result = orders.reduce(function (r, a) {
   r[a.itemCount] = r[a.itemCount] || [];
   r[a.itemCount].push(a);
   return r;
}, Object.create(null));

console.log(result);

but this is not what I want. How can I do this? Any example will be appreciated!

Upvotes: 1

Views: 67

Answers (2)

phi-rakib
phi-rakib

Reputation: 3302

You can use array reduce method to count the frequency of itemCount. After that use Object.keys to get all the keys and use array map method to create a new object.

const orders = [
  {
    oreder: 'Order/1',
    itemCount: 2,
  },
  {
    oreder: 'Order/2',
    itemCount: 1,
  },
  {
    oreder: 'Order/3',
    itemCount: 3,
  },
  {
    oreder: 'Order/4',
    itemCount: 2,
  },
  {
    oreder: 'Order/5',
    itemCount: 2,
  },
  {
    oreder: 'Order/6',
    itemCount: 1,
  },
];

let ret = orders.reduce((prev, c) => {
  const p = prev;
  const key = c.itemCount;
  if (!p[key]) p[key] = 1;
  else p[key] += 1;
  return p;
}, {});

ret = Object.keys(ret).map((x) => ({
  itemCount: x,
  numberOfOrders: ret[x],
}));

console.log(ret);

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386766

You need to count instead of collecting items in an array. At the end take the value form the object.

const
    orders = [{ order: "Order/1", itemCount: 2 }, { order: "Order/2", itemCount: 1 }, { order: "Order/3", itemCount: 3 }, { order: "Order/4", itemCount: 2 }, { order: "Order/5", itemCount: 2 }, { order: "Order/6", itemCount: 1}],
    result = Object.values(orders.reduce(function(r, { itemCount }) {
        r[itemCount] = r[itemCount] || { itemCount, numberOfOrders: 0 };
        r[itemCount].numberOfOrders++;
        return r;
    }, Object.create(null)));

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

Upvotes: 1

Related Questions