2013-05-21 35 views
3

我有在JS的阵列内的三个对象像下面Javascript对象总和值effeicently

[{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}] 

我想类似下面作为由上述阵列输出。

[{"2013-03-02T00:00": 350} , {"2013-03-01T00:00": 200}] 

它可以通过循环和添加来完成,有没有什么有效的方法可以做到这一点?

在此先感谢。

+1

你在这添加什么?你能否更新你的问题来描述一下? –

+1

啊。我懂了。你的问题有点不清楚,但你基本上想要添加所有类似的键。 –

+0

您是否仍然可以将数组更改为包含以下内容的项目:{'date':“2013-03-02T00:00”,value:300}这样可以更轻松地组合项目和添加值,因为您可以对数组进行排序日期并在同一个清晰的飞行中获得相同的值。 – HMR

回答

4
var myList = [{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}]; 
var result = {}; 
var item = null, key = null; 
for(c=0; c<myList.length; c++) { 
    item=myList[c]; 
    key = Object.keys(item)[0]; 
    item=item[key]; 

    if(!result[key]) result[key] = item; 
    else result[key] += item; 
} 

console.log(result); 

我把它作为练习让读者把结果写入请求的表格。 (毕竟你应该至少自己解决一部分问题:)

+0

您的var c在for循环中未定义,无法编辑,因为需要编辑的字符的最小值 – Octavioamu

0

你可能想看看underscore.js,它有许多有用的操作和处理数据的高效函数的实现。特别是,你要在_.groupBy功能来一看:

var data = [{"2013-03-02T00:00": 300}, {"2013-03-01T00:00": 200},{"2013-03-02T00:00": 50}] 
_.groupBy(data, function(obj) { return Object.keys(obj)[0]; }) 

你最好还是要遍历和值相加,但是这就是为什么我们有减少的功能!

如果你想要更具体到你的用例,我会看看github上的源代码。

https://github.com/documentcloud/underscore

1

如果你可以添加键值“日期”,你可以进行排序和分组它的对象的另一个值,当你有数组中更多的价值,这将是更快,更优化。

[更新]:修正了一个小错误。

var arr = [{"date":"2013-03-02T00:00",val: 300} 
, {"date":"2013-03-01T00:00",val: 200} 
,{"date":"2013-03-02T00:00",val: 50}]; 
function groupArray(arr){ 
    if(arr.length===0){return [];} 
    var pref,i; 
    // sort by date 
    arr.sort(function(a,b){ 
    return (a.date>b.date)?1:(a.date<b.date)?-1:0; 
    }); 
    // loop through the array grouping objects by date 
    pref=arr[0].date; 
    for(i=1;i<arr.length;i++){ 
    if(arr[i].date===pref){ 
     //set the total 
     arr[i-1].val=arr[i-1].val+arr[i].val; 
     //remove the element 
     arr.splice(i,1); 
     // set i one back 
     i--; 
    } 
    pref=arr[i].date; 
    } 
    return arr; 
} 
console.log(groupArray(arr)); 

一个更复杂的例子是,当你动态地要提供密钥进行排序,在按键上面的例子是“硬编码”是日期,但您也许需要组上的另一个关键值时,以下是一段代码,我已经简化了一组密钥(原始使用的是一组密钥)。您可以传递一个onMerge变量,该变量应该是处理如何合并2个项目的函数。该函数不是通用的,并且特定于添加待合并对象的val属性。

var arr = [{"date":"2013-03-02T00:00",val: 300} 
, {"date":"2013-03-01T00:00",val: 200} 
, {"date":"2013-03-01T00:00",val: 200} 
, {"date":"2013-03-01T00:00",val: 200} 
, {"date":"2013-03-01T00:00",val: 200} 
,{"date":"2013-03-02T00:00",val: 50}]; 
/** 
* @param arr is the array to be merged 
* @param key is the key to use for merge 
* (like date) will merge on items with same 
* date value 
* @param onMerge function to call when 2 items 
* are merged with the 2 items as parameters 
**/ 
function groupArray(arr,key,onMerge){ 
    if(arr.length===0){return [];} 
    var pref,i; 
    // sort by key 
    arr.sort(function(a,b){ 
    return (a[key]>b[key])?1:(a[key]<b[key])?-1:0; 
    }); 
    // loop through the array grouping objects by key 
    pref=arr[0][key]; 
    for(i=1;i<arr.length;i++){ 
    if(arr[i][key]===pref){ 
     //merge 2 items, call the onMerge callback 
     arr[i-1]=onMerge(arr[i-1],arr[i]); 
     //remove the element 
     arr.splice(i,1); 
     // set i one back 
     i--; 
    } 
    pref=arr[i][key]; 
    } 
    return arr; 
} 
// functon that will be called when 2 items are merged 
// stay will stay and gone will be gone 
// this function is specific to your data type 
function onMergeCallback(stay,gone){ 
    stay.val=stay.val+gone.val; 
    return stay; 
} 

console.log(groupArray(arr,"date",onMergeCallback));