将对象数组({a:a,b:b,c:c},{a:a,d:d,c:c})组合为({a:a,b:c,d:c}) [英] Combining object arrays ({a:a,b:b, c:c},{a:a,d:d,c:c}) to ({a:a,b:c,d:c})
问题描述
我有一个要获取的数据列表,我需要将其转换并透视"以将一列变成多列.
I have a list of data that I'm getting that I need to convert and "pivot" to turn one column into multiple columns.
我拥有的对象列表如下:
The list of objects I have looks like this:
var list = [
{
"date": "2016-05-31",
"action": "test",
"value": 10
},
{
"date": "2016-05-31",
"action": "run",
"value": 8
},
{
"date": "2016-06-01",
"action": "delete",
"value" : 2
},
{
"date": "2016-06-01",
"action": "test",
"value": 5
},
]
我需要将其转换为图表库,使其看起来像这样:
I need to convert this for a charting library so that it looks like this:
var list = [
{
"date": "2016-05-31",
"test": 10,
"run": 8,
"delete": 0
},
{
"date": "2016-06-01",
"test": 5,
"run": 0,
"delete": 2
}
]
是否有使用_.groupBy和_.map等underscore.js函数的简便方法?
Is there a fairly easy way to do this using underscore.js functions like _.groupBy and _.map etc...?
推荐答案
这是ES6解决方案,它不会对test
,run
或delete
进行硬编码,但首先会检索数据中所有可能的操作:
Here is an ES6 solution, which does not hard-code test
, run
or delete
, but first retrieves all possible actions in the data:
function pivot(list) {
var actions = list.reduce( (actions, o) => (actions[o.action] = 0, actions), {} );
var res = list.reduce( (res, o) => ((res[o.date] = res[o.date] || Object.assign({ date: o.date }, actions))[o.action] += o.value, res), {});
return Object.keys(res).map(key => res[key]);
}
// Sample data
var list = [{
"date": "2016-05-31",
"action": "test",
"value": 10
}, {
"date": "2016-05-31",
"action": "run",
"value": 8
}, {
"date": "2016-06-01",
"action": "delete",
"value": 2
}, {
"date": "2016-06-01",
"action": "test",
"value": 5
}];
// Call
var res = pivot(list);
// Output
console.log(res);
如果在同一日期重复一个动作值,则将相应的值相加(假定为数值).
If an action value is repeated for the same date the corresponding values are added together (so numerical values are assumed).
在对速度的评论之后,我在这里介绍一个函数,该函数可以在一个循环中完成这项工作:
Following the comments on speed, I present here a function that does the job in one loop:
var list = [{
"date": "2016-05-31",
"action": "test",
"value": 10
}, {
"date": "2016-05-31",
"action": "run",
"value": 8
}, {
"date": "2016-06-01",
"action": "delete",
"value": 2
}, {
"date": "2016-06-01",
"action": "test",
"value": 5
}];
function pivot(list) {
var res = {}, arr = [];
for (var o of list)
(res[o.date] || (arr[arr.push(res[o.date] = {
date: o.date,
test: 0,
run : 0,
"delete": 0
})-1]))[o.action] += o.value;
return arr;
}
var res = pivot(list);
console.log(res);
我已将其添加到测试服 Ismail RBOUH中创建.
I have added this to the test suit Ismail RBOUH created.
这篇关于将对象数组({a:a,b:b,c:c},{a:a,d:d,c:c})组合为({a:a,b:c,d:c})的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!