我在 JS 的数组中确实有三个对象,如下所示
[{"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}]
可以通过循环和添加来完成,有什么有效的方法可以做到吗?
提前致谢。
我在 JS 的数组中确实有三个对象,如下所示
[{"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}]
可以通过循环和添加来完成,有什么有效的方法可以做到吗?
提前致谢。
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);
我将其作为练习留给读者将结果放入请求的表格中。(毕竟你应该自己解决至少部分问题:)
如果您可以将键“日期”添加为对象的另一个值,您可以对其进行排序和分组,当数组中有更多值时,这将更快、更优化。
[更新]:修复了一个小错误。
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));
你可能想看看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]; })
您仍然需要对值进行迭代和求和,但这就是我们使用 reduce 函数的原因!
如果您想要更具体的用例,我会查看 github 上的源代码。