Reputation: 3
First question on here so please feel free to point out what I should be doing differently or if there are other threads I should refer to.
I have array of objects that look like this:
const fetchResults = [ {
date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]
I need a payload that returns the sum of the quantity and amount for each trade date and symbol. Specifically, in this example, it would total the quantity and amount for the 3 objects with TLTE and 3/20/20. The payload results would look like this:
const payloadResults = [ {
date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 385, amount: 13765.53,
}, {
date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]
Here's the code I've tried:
const fetchResults = [ {
trade_date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
trade_date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
trade_date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
trade_date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
trade_date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
trade_date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]
const payloadResults = []
const uniqueTradeDates = Array.from(new Set(fetchResults.map(({ trade_date }) => trade_date)))
const uniqueSecurityIds = Array.from(new Set(fetchResults.map(({ symbol }) => symbol)))
for (const td of uniqueTradeDates) {
for (const s of uniqueSecurityIds) {
const results = fetchResults.filter((r) => r.symbol === s && r.trade_date === td)
if (results.length > 0) {
const totalQuantity = results.reduce((a, b) => a + b.quantity, 0)
const totalAmount = results.reduce((a, b) => a + b.amount, 0)
payloadResults.push({
trade_date: td, symbol: s, quantity: totalQuantity, amount: totalAmount,
})
}
}
}
console.log(payloadResults)
Thanks for your help!
Upvotes: 0
Views: 133
Reputation: 2829
var fetchResults = [
{date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570},
{date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000},
{date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222},
{date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02},
{date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51},
{date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000}
];
function sumResults(a) {
var b = {}, c = [], d = 0;
a.forEach(function(e) {
var f = e.date + e.symbol;
if(f in b) c[b[f]].quantity += e.quantity,
c[b[f]].amount += e.amount;
else b[f] = d++, c.push(e);
});
return c;
}
console.log(sumResults(fetchResults));
Upvotes: 0
Reputation: 17238
Reorganize the source array into a nested 2-level dictionary and compute the totals by iterating over dictionary entries:
const fetchResults = [ {
date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
}
];
function aggregate () {
let dict_aggregate = {}
;
fetchResults.forEach ( (item, idx) => {
if (dict_aggregate[item.date] === undefined) {
dict_aggregate[item.date] = {};
}
if (dict_aggregate[item.date][item.symbol] === undefined) {
dict_aggregate[item.date][item.symbol] = { quantity: 0, amount: 0.0 };
}
dict_aggregate[item.date][item.symbol].quantity += item.quantity;
dict_aggregate[item.date][item.symbol].amount += item.amount;
});
let a_results = [];
for (let [s_keyDate, dict_bySymbol] of Object.entries(dict_aggregate)) {
for (let [s_keySymbol, dict_totals] of Object.entries(dict_bySymbol)) {
a_results.push ({
date: s_keyDate
, symbol: s_keySymbol
, quantity: dict_totals.quantity
, amount: dict_totals.amount
});
}
}
return a_results;
}
let payloadResults = aggregate()
;
console.log(JSON.stringify(payloadResults));
Upvotes: 0
Reputation: 207511
Just a simple loop with reduce to make up an object that has a key made up of the fields that make them duplicates. In this case it is the symbol and the date. So loop over making a key with those two fields. Check to see if we have seen it before, if we have, we just update the quantity and amount. If not, we just add the record.
const fetchResults = [ {
date: '03/20/2020', symbol: 'TLTE', quantity: 100, amount: 3570,
}, {
date: '03/20/2020', symbol: 'GE', quantity: 100, amount: 10000,
}, {
date: '03/20/2020', symbol: 'AAPL', quantity: 50, amount: 22222,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 4, amount: 161.02,
}, {
date: '03/20/2020', symbol: 'TLTE', quantity: 281, amount: 10034.51,
}, {
date: '03/21/2020', symbol: 'TLTE', quantity: 200, amount: 8000,
} ]
// Object values returns the values of all the properties in an object
const results = Object.values(
// we are going to take our array and create a lookup object using reduce
fetchResults.reduce((obj, data) => {
// generate the key for our lookup object
const key = data.symbol + data.date
// check to see if the result exists yet
const dayResult = obj[key]
// if it exists we updated the record values
if (dayResult) {
dayResult.quantity += data.quantity
dayResult.amount += data.amount
} else {
// if it does not exist we copy the record into the key we made
obj[key] = { ...data }
}
// return our lookup data
return obj
}, {})
)
console.log(results)
Upvotes: 1