Javascript 将对象数组({a:a,b:b,c:c},{a:a,d:d,c:c})组合到({a:a,b:c,d:c})

Javascript 将对象数组({a:a,b:b,c:c},{a:a,d:d,c:c})组合到({a:a,b:c,d:c}),javascript,jquery,underscore.js,Javascript,Jquery,Underscore.js,我有一个我需要转换的数据列表,并“透视”将一列转换为多列 我拥有的对象列表如下所示: var list = [ { "date": "2016-05-31", "action": "test", "value": 10 }, { "date": "2016-05-31", "action": "run", "value": 8 }, { "date": "2016-06-01", "action": "delete", "v

我有一个我需要转换的数据列表,并“透视”将一列转换为多列

我拥有的对象列表如下所示:

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
},
]
var list = [
{
    "date": "2016-05-31",
    "test": 10,
    "run": 8,
    "delete": 0
},
{
    "date": "2016-06-01",
    "test": 5,
    "run": 0,
    "delete": 2
}
]
我需要将其转换为图表库,使其如下所示:

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
},
]
var list = [
{
    "date": "2016-05-31",
    "test": 10,
    "run": 8,
    "delete": 0
},
{
    "date": "2016-06-01",
    "test": 5,
    "run": 0,
    "delete": 2
}
]

是否有一种相当简单的方法可以使用underline.js函数(如u.groupBy和.map等)执行此操作?

此方法会迭代两次以创建日期映射,然后再次迭代以插入缺少的属性

var列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}];
var-map={};
list.forEach(函数(o){
如果(!(映射中的o.date))映射[o.date]={};
map[o.date][o.action]=o.value;
});
var sorted_list=Object.keys(map).map(函数(k){
返回{
“日期”:k,
“测试”:(映射[k]。测试| | 0),
“运行”:(映射[k]。运行| | 0),
“删除”:(映射[k]。删除| | 0)
}
});

document.body.innerHTML=''+JSON.stringify(排序列表,0,4)+''这将迭代两次以创建日期映射,然后再次迭代以插入缺少的属性

var temp = list.reduce(function(c, v) {
  (c[v.date] || (c[v.date]={}))[v.action] = v.value;
  return c;
}, {});
var output = Object.keys(temp).map(function(k) {
  return {
    date : k,
    test : temp[k].test || 0,
    run : temp[k].run || 0,
    "delete" : temp[k].delete || 0
  }
});
var列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}];
var-map={};
list.forEach(函数(o){
如果(!(映射中的o.date))映射[o.date]={};
map[o.date][o.action]=o.value;
});
var sorted_list=Object.keys(map).map(函数(k){
返回{
“日期”:k,
“测试”:(映射[k]。测试| | 0),
“运行”:(映射[k]。运行| | 0),
“删除”:(映射[k]。删除| | 0)
}
});

document.body.innerHTML=''+JSON.stringify(排序列表,0,4)+''
这里有一种方法,使用
.reduce()
创建一个临时对象来累积值,然后使用
.map()
创建最终数组:

var temp = list.reduce(function(c, v) {
  (c[v.date] || (c[v.date]={}))[v.action] = v.value;
  return c;
}, {});
var output = Object.keys(temp).map(function(k) {
  return {
    date : k,
    test : temp[k].test || 0,
    run : temp[k].run || 0,
    "delete" : temp[k].delete || 0
  }
});
var result = _.chain(list).groupBy("date")
.mapObject(function(item, key) {    
    var d = {date: key};
    for(var i in item) d[item[i].action] = item[i].value;
    return d;
}).values().value();

这里有一种方法,使用
.reduce()
创建一个临时对象来累积值,然后使用
.map()
创建最终数组:

var result = _.chain(list).groupBy("date")
.mapObject(function(item, key) {    
    var d = {date: key};
    for(var i in item) d[item[i].action] = item[i].value;
    return d;
}).values().value();

这里是一个ES6解决方案,它不硬编码
测试
运行
删除
,而是首先检索数据中所有可能的操作:

功能轴(列表){
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),{});
返回Object.keys(res.map)(key=>res[key]);
}
//样本数据
变量列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}];
//召唤
var res=枢轴(列表);
//输出

控制台日志(res)这里有一个ES6解决方案,它不硬编码
测试
运行
删除
,而是首先检索数据中所有可能的操作:

功能轴(列表){
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),{});
返回Object.keys(res.map)(key=>res[key]);
}
//样本数据
变量列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}];
//召唤
var res=枢轴(列表);
//输出

控制台日志(res)下面是一个下划线解决方案:

var列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}, ];
var结果=uu.chain(list.groupBy)(“日期”)
.mapObject(函数(项,键){
var d={date:key};
对于(项目中的变量i)d[项目[i]。操作]=项目[i]。值;
返回d;
}).values().value();
控制台日志(结果)

下面是一个下划线解决方案:

var列表=[{
“日期”:“2016-05-31”,
“行动”:“测试”,
“价值”:10
}, {
“日期”:“2016-05-31”,
“操作”:“运行”,
“价值”:8
}, {
“日期”:“2016-06-01”,
“行动”:“删除”,
“价值”:2
}, {
“日期”:“2016-06-01”,
“行动”:“测试”,
“价值”:5
}, ];
var结果=uu.chain(list.groupBy)(“日期”)
.mapObject(函数(项,键){
var d={date:key};
对于(项目中的变量i)d[项目[i]。操作]=项目[i]。值;
返回d;
}).values().value();
控制台日志(结果)

如果不进行解释,映射标准就不完全直观问题标题中的示例映射输入数组中存在的属性/值。问题正文中的完整示例创建不在原始数组中的属性,例如将
delete
添加到2016-05-31日期。如果在同一日期定义了多个
test
属性,您会期望发生什么?我已经对建议的解决方案进行了基准测试,下面是结果。最快的是adeneo;)。啊,所以速度是你的主要目标。。。我在你的问题中漏掉了。我以为你在找相当简单的;-)我还应该注意到,我在Chrome中也有同样的结果,但在FireFox中,NNN的解决方案运行速度始终快于Chrome