我有两个对象数组。其中一人每天有访客数量,其他人每天有文件数。像这样:
var visitors = [ { '2014.12.25': 141 }, { '2014.12.26': 630 }, { '2014.12.30': 71 } ];
var documents = [ { '2014.12.15': 31 }, { '2014.12.26': 60, }, { '2014.12.30': 95 } ];
每个数组的日期可能不同。 如何将数组转换为以下结构(意味着按日期键组合它们):
[ { date: '2014.12.15', visits: 0, docs: 31 }, // here visits = 0 because there were no visitors at this date
{ date: '2014.12.25', visits: 441, docs: 0 }, // here docs = 0 because no docs were created at this date
{ date: '2014.12.26', visits: 630, docs: 60 },
{ date: '2014.12.30', visits: 71, docs: 95 },
]
允许使用的工具:JavaScript
和Undescore.js
。
谢谢
答案 0 :(得分:1)
让我们在原生JS中了解一下。
首先,让我们将这两个数组转化为更明智的对象:
function reduceDates(prev, curr){
var date = Object.keys(curr)[0]; // This is why {date : value} makes no sense.
prev[date] = curr[date];
return prev;
}
var v = visitors.reduce(reduceDates, {}); // {2014.12.25: 141, 2014.12.26: 630, 2014.12.30: 71}
var d = documents.reduce(reduceDates, {}); // {2014.12.15: 31, 2014.12.26: 60, 2014.12.30: 95}
让这些2合并为一个对象:
var combined = {};
for(var key in v){
combined[key] = { date: key, visits: v[key], docs: 0 };
}
for(var key in d){
combined[key] = combined[key] || { date: key, visits: 0 };
combined[key].docs = d[key];
}
现在,combined
是一个包含数据的非常好的对象:
{
"2014.12.25": { date: "2014.12.25", visits: 141, docs: 0 },
"2014.12.26": { date: "2014.12.26", visits: 630, docs: 60 },
"2014.12.30": { date: "2014.12.30", visits: 71, docs: 95 },
"2014.12.15": { date: "2014.12.15", visits: 0, docs: 31 }
}
但是,由于您需要一组对象,我们将不得不再次迭代:
var result = [];
for(var key in combined){
result.push(combined[key]);
}
结果:
[
{ date: "2014.12.25", visits: 141, docs: 0 },
{ date: "2014.12.26", visits: 630, docs: 60 },
{ date: "2014.12.30", visits: 71, docs: 95 },
{ date: "2014.12.15", visits: 0, docs: 31 }
]
当然,这不是获得所需结果的最短或最佳方式,但我希望它能让您了解此过程中涉及的步骤。
答案 1 :(得分:0)
您所要做的就是循环数据。
var visitors = [ { '2014.12.25': 141 }, { '2014.12.26': 630 }, { '2014.12.30': 71 } ];
var documents = [ { '2014.12.15': 31 }, { '2014.12.26': 60, }, { '2014.12.30': 95 } ];
var data = {};
visitors.forEach(function(el){var k = Object.keys(el)[0]; data[k] = data[k] || {}; data[k].visits = el[k];});
documents.forEach(function(el){var k = Object.keys(el)[0]; data[k] = data[k] || {}; data[k].docs = el[k];});
for(prop in data){
if(data[prop].docs === void 0){data[prop].docs = 0};
if(data[prop].visits === void 0){data[prop].visits = 0};
}
这会以组合的方式提供您的数据,您只需添加逻辑以将日期从键移动到属性。
答案 2 :(得分:0)
使用下划线组合数组的另一种方法:
var visitors = [ { '2014.12.25': 141 }, { '2014.12.26': 630 }, { '2014.12.30': 71 } ];
var documents = [ { '2014.12.15': 31 }, { '2014.12.26': 60, }, { '2014.12.30': 95 } ];
var visits = new Array();
var docs = new Array();
for (i=0; i < visitors.length; i++) {
for (key in visitors[i]) {
visits.push({"date": key, "visits": visitors[i][key], "docs":0});
}
}
for (i=0; i < documents.length; i++) {
for (key in documents[i]) {
docs.push({"date": key,"docs": documents[i][key]});
}
}
mergeByProperty(visits, docs, 'date');
function mergeByProperty(visits, docs, prop) {
_.each(docs, function(arr2obj) {
var arr1obj = _.find(visits, function(arr1obj) {
return arr1obj[prop] === arr2obj[prop];
});
//If the object already exist extend it with the new values from arr2, otherwise just add the new object to arr1
arr1obj ? _.extend(arr1obj, arr2obj) : visits.push(arr2obj);
});
}
console.log(visits);