javascript对象文字,组合同一文字内的对象的值

时间:2013-07-19 13:38:53

标签: javascript arrays javascript-objects object-literal

我正在尝试通过循环遍历下面并组合具有相似类型的对象的值来创建新对象?

所以我有这样的事情:

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

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

非常感谢任何帮助。

3 个答案:

答案 0 :(得分: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}
] */

答案 1 :(得分: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制作的修补程序告诉我我的代码不起作用。这个,见the FIDDLE

答案 2 :(得分: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)”语法。