Reputation: 4539
I am trying to create a new object from looping through the below and combining values of objects that have like types?
so I have something like this:
var data = [{
transID: 123,
repId: 86,
profit: 117.3,
expense: 96.76 },
{
transID: 124,
repId: 35,
profit: 47.39,
expense: 15.15 },
{
transID: 125,
repId: 86,
profit: 62.62,
expense: 15.17 }]
So i need to create a new array same as above, only for each rep I want one object with a sum of the profit and expense like (so no transID either):
[{
repId: 86,
profit: 179.92,
expense: 111.93 },
{
repId: 35,
profit: 47.39,
expense: 15.15 }]
i am just learning (go easy this may be totally wrong) but I have tried things like:
var otherData = [];
for ( var i = 0; i < data.length; i++ ) {
var thisDataObj = data[i];
for ( var j = 0; j < data.length; i++) {
var thisComparedData = data[j]; // maybe a ridiculous approach ??
if(thisDataObj.repId == thisComparedData.repId) {
if(thisDataOjb.transId != thisComparedData.transId) {
// struggling with this part if this is event the right approach
// the loop is bad because it will recount
}
}
}
so without showing the things i tried within that loop, i am pretty sure this is just wrong as it will recount values if I tried to sum, create the object and push it. just not sure what is a better way?
any help is greatly appreciated.
Upvotes: 0
Views: 495
Reputation: 15397
Sort your array based on repId
:
data.sort(function(a,b) { return a.repId - b.repId });
Now you can just loop through data
, looking to see when repId
changes:
var prevValue = data[0].repId; // initialize with first data set
var profit = data[0].profit;
var expense = data[0].expense;
for (var i = 1; i < data.length; ++i) {
var thisDataObj = data[i];
alert("Start of loop. prevValue = " + prevValue + ", repId = " + thisDataObj.repId);
if (thisDataObj.repId == prevValue) {
profit += thisDataObj.profit;
expense += thisDataObj.expense;
alert("profit = " + profit + ", expense = " + expense);
} else {
alert("prevValue = " + prevValue + ", profit = " + profit + ", expense = " + expense);
otherData.push({
repId: prevValue,
profit: profit,
expense: expense
});
prevValue = thisDataObj.repId;
profit = thisDataObj.profit;
expense = thisDataObj.expense;
}
}
otherData.push({ // add the last value, since there won't be a change detected for it
repId: prevValue,
profit: profit,
expense: expense
});
If you don't want to change the data
array by sorting it, make a copy first using:
var newArray = data.concat();
EDIT Made fixes based on Bergi telling me my code doesn't work. This one does, see the FIDDLE.
Upvotes: 2
Reputation: 664630
just not sure what is a better way?
Yes, you can use an object as a lookup map for new objects by repId:
var map = {};
for (var i=0; i<data.length; i++) {
var obj = data[i],
id = obj.repId;
if (id in map) { // we know this id already
// get the object and sum properties
map[id].profit += obj.profit;
map[id].expense += obj.expense;
} else // create a new one
map[id] = {
repId: id,
profit: obj.profit,
expense: obj.profit
};
}
/* map:
{
"35":{"repId":35,"profit":47.39,"expense":47.39},
"86":{"repId":86,"profit":179.92,"expense":132.47}
} */
// put the values from the map in an array
var otherData = [];
for (var id in map)
otherData.push(map[id]);
/* otherData:
[
{"repId":35,"profit":47.39,"expense":47.39},
{"repId":86,"profit":179.92,"expense":132.47}
] */
Upvotes: 3
Reputation: 133
I'm a little unclear on the exact math you're trying to achieve, but I think I can help with the looping. You don't need two loops, just one to iterate through the array of data objects. Then, build yourself a new array of your new objects. Like:
var newData = [];
for (var i=0; i<data.length; i++) {
var currentDataObject = data[i]; // don't really need this but just to make it clear
newData.push({
repId: currentDataObject.repId,
profit: your math here,
expense: your math
});
}
For the record though, if you did need to iterate through the properties of an object, you'd need to use the "for (var key in data)" syntax.
Upvotes: 0