0

我正在尝试通过循环以下内容并组合具有相似类型的对象的值来创建一个新对象?

所以我有这样的事情:

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

所以我需要创建一个与上面相同的新数组,仅对于每个代表我想要一个具有利润和费用总和的对象(所以也没有 transID):

            [{ 
                repId: 86,
                profit: 179.92,
                expense: 111.93 },
             {
                repId: 35,
                profit: 47.39,
                expense: 15.15 }]

我只是在学习(放轻松,这可能是完全错误的),但我尝试过类似的方法:

    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
        }
      }
    }

所以没有显示我在那个循环中尝试的东西,我很确定这是错误的,因为如果我尝试求和,创建对象并推送它,它将重新计算值。只是不确定什么是更好的方法?

任何帮助是极大的赞赏。

4

3 回答 3

3

只是不确定什么是更好的方法?

是的,您可以通过 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}
] */
于 2013-07-19T13:55:21.523 回答
2

根据以下对数组进行排序repId

data.sort(function(a,b) { return a.repId - b.repId });

现在你可以遍历data,看看什么时候repId发生变化:

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
});

如果您不想data通过排序来更改数组,请先使用以下命令进行复制:

var newArray = data.concat();

编辑根据 Bergi 告诉我我的代码不起作用进行了修复。这个可以,见FIDDLE

于 2013-07-19T13:54:39.350 回答
0

我对你想要达到的确切数学有点不清楚,但我想我可以帮助循环。您不需要两个循环,只需一个循环即可遍历数据对象数组。然后,为自己构建一个新对象的新数组。喜欢:

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 (var key in data)”语法。

于 2013-07-19T13:52:55.623 回答