質問

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.

役に立ちましたか?

解決

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}
] */

他のヒント

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.

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top