1

I have an API that returns data such as this:

{
        "attributes": {
            "type": "Opportunity"
        },
        "Amount": 175.36,
        "Owner": {
            "attributes": {
                "type": "User"
            },
            "Name": "Steve Knight"
        }
    },

    {
        "attributes": {
            "type": "Opportunity"
        },
        "Amount": 6800,
        "Owner": {
            "attributes": {
                "type": "User"
            },
            "Name": "Bob Smith"
        }
    }
etc...

These represent opportunities and so each salesperson will have multiple. I am trying to return an object that sums the amounts for each salesperson and returns something like:

{Steve Knight: 5590, Bob Smith: 98722, John Jones: 12347893}

I have tried grouping the objects by owner name however I am not sure how to then sum the amounts

var groupBy = require('lodash.groupby');

var grouped = groupBy(data, function(x) {
        return x.Owner.Name;
      });
Will Rollason
  • 125
  • 1
  • 1
  • 10
  • Have a look on this: https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects – Sunil tc Mar 11 '20 at 10:36

3 Answers3

2

Best to use the reduce method of Array.prototype

console.clear();

(function() {
  "use strict";

  function reduce(coll, elem, idx, arr) {
    coll[elem.Owner.Name] = coll[elem.Owner.Name] || 0;
    coll[elem.Owner.Name] += elem.Amount

    return coll;
  }

  const data = [
    {
      attributes: {
        type: "Opportunity"
      },
      Amount: 175.36,
      Owner: {
        attributes: {
          type: "User"
        },
        Name: "Steve Knight"
      }
    },

    {
      attributes: {
        type: "Opportunity"
      },
      Amount: 100.16,
      Owner: {
        attributes: {
          type: "User"
        },
        Name: "John Doe"
      }
    },

    {
      attributes: {
        type: "Opportunity"
      },
      Amount: 6.00,
      Owner: {
        attributes: {
          type: "User"
        },
        Name: "John Doe"
      }
    },

    {
      attributes: {
        type: "Opportunity"
      },
      Amount: 101.65,
      Owner: {
        attributes: {
          type: "User"
        },
        Name: "Steve Knight"
      }
    },

    {
      attributes: {
        type: "Opportunity"
      },
      Amount: 6800,
      Owner: {
        attributes: {
          type: "User"
        },
        Name: "Bob Smith"
      }
    }
  ];

  const reducedData = data.reduce(reduce, {})

  console.log(reducedData)
}());
yunzen
  • 32,854
  • 11
  • 73
  • 106
1

If key name exists than accumulate the already existing value to the new one, otherwise just add the initial value and name

const arr = [{
    "attributes": {
      "type": "Opportunity"
    },
    "Amount": 175.36,
    "Owner": {
      "attributes": {
        "type": "User"
      },
      "Name": "Steve Knight"
    }
  },
  {
    "attributes": {
      "type": "Opportunity"
    },
    "Amount": 100,
    "Owner": {
      "attributes": {
        "type": "User"
      },
      "Name": "Steve Knight"
    }
  },

  {
    "attributes": {
      "type": "Opportunity"
    },
    "Amount": 6800,
    "Owner": {
      "attributes": {
        "type": "User"
      },
      "Name": "Bob Smith"
    }
  }
]


const result = arr.reduce((acc, x) => {
  const key = x.Owner.Name;
  const amount = x['Amount'];

  if (!acc[key]) {
    acc[key] = amount;
  } else {
    acc[key] = acc[key] + amount;
  }

  return acc;
}, {});
console.log(result)
EugenSunic
  • 13,162
  • 13
  • 64
  • 86
  • Is there a reason why you write `acc = { ...acc, [key]:amount}` instead of simply `acc[key] = amount` ? – rplantiko Mar 11 '20 at 10:52
  • 1
    @rplantiko you are right, just got used it because of mutating the sate sometimes, it doesn't impact the performance anyways and garbage collector does it's job pretty well – EugenSunic Mar 11 '20 at 10:56
  • By `sate` you mean `state` – yunzen Mar 11 '20 at 12:33
0

You can try this below:

let output = {}
data.map(function (item) {
    if (output.hasOwnProperty(item.Owner.Name)) {
            output[item.Owner.Name] = item.Amount;
    } else {
            output[item.Owner.Name] += item.Amount;
    }
 });
Abhishek Kulkarni
  • 1,747
  • 1
  • 6
  • 8