首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合对象数组({a:a,b:b,c:c},{a:a,d:d,c:c})到({a:a,b:c,d:c})

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

Stack Overflow用户
提问于 2016-07-16 07:37:49
回答 4查看 99关注 0票数 0

我有一个数据列表,我需要对其进行转换和“透视”,以将一列转换为多列。

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

代码语言:javascript
复制
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
},
]

我需要将它转换为一个图表库,这样它看起来就像这样:

代码语言:javascript
复制
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函数来实现这一点呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-07-16 08:36:52

这是一个ES6解决方案,它不对testrundelete进行硬编码,而是首先检索数据中所有可能的操作:

代码语言:javascript
复制
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);

如果动作值在同一日期内重复,则相应的值将被相加在一起(因此假定为数值)。

另一种专注于速度的方法

在对速度的评论之后,我在这里提供了一个在一个循环中完成这项工作的函数:

代码语言:javascript
复制
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);

我已经将其添加到创建的the test suit Ismail RBOUH中。

票数 1
EN

Stack Overflow用户

发布于 2016-07-16 07:50:32

这将迭代两次以创建日期映射,然后再次迭代以插入缺少的属性?

代码语言:javascript
复制
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 map = {};

list.forEach(function(o) {
	if ( !(o.date in map) ) map[o.date] = {};
   	map[o.date][o.action] = o.value;
});

var sorted_list = Object.keys(map).map(function(k) {
	return {
    	"date"   : k,
    	"test"   : (map[k].test || 0),
        "run"    : (map[k].run || 0),
        "delete" : (map[k].delete || 0)
    }
});

document.body.innerHTML = '<pre>' + JSON.stringify(sorted_list, 0, 4) + '</pre>';

票数 2
EN

Stack Overflow用户

发布于 2016-07-16 07:55:08

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

代码语言:javascript
复制
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
  }
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38406333

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档