2013-07-19 31 views
0

我想创建一个新的对象,通过下面的循环,并结合具有类型的对象的值?JavaScript对象文字,结合在同一文字内的对象的值

所以我有这样的事情:

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

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

是的,你可以使用一个对象作为查找图新对象由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} 
] */ 
+0

这真的帮助了我....我学到了新的东西,很酷。谢谢! – Justin

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

为了记录在案不过,如果你确实需要通过一个对象的属性进行迭代,你需要使用“为(VAR的关键数据)”语法。

+0

'选择REPID,SUM(利润),SUM(费用)FROM数据GROUPBY(REPID)'如果你知道SQL吗?你的脚本不能做到这一点。 – Bergi

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

+0

用'O(n log n)'运行时(不是最优的但比n 2好)的好主意。然而,它不能像现在写的那样工作 - 你应该试试你的代码:-) – Bergi

+0

@Bergi嗯,我对聚会有点晚了,但我修正了一些并且检查了我的代码。 (不是非常健壮,但应该足够了。)谢谢你的鼓励。 :-) –

+1

谢谢:-)顺便说一句,你可以缩短排序'data.sort(函数(a,b){返回a.repId-b。REPID; })' – Bergi

相关问题