包含数组的对象数组的对象数组

时间:2017-03-03 23:08:24

标签: javascript arrays javascript-objects

我有一系列对象:

 var arr = [
    {
        timemark: "2017-03-01",
        db_total: c1,
        db_used: d1,
        hosts: e1,
        items: f1
    },{
        timemark: "2017-03-02",
        db_total: c2,
        db_used: d2,
        hosts: e2,
        items: f2
    },{
        timemark: "2017-03-03",
        db_total: c3,
        db_used: d3,
        hosts: e3,
        items: f3
    },..]

我正在思考如何将它转换为另一个阵列,但结构不同:

var result = [
    {
        topic: "db_total",
        data: [
            {
                x: "2017-03-01",
                y: c1
            },{
                x: "2017-03-02",
                y: c2
            },{
                x: "2017-03-03",
                y: c3
            },...]
    },{
        topic: "db_used",
        data: [
            {
                x: "2017-03-01",
                y: d1
            },{
                x: "2017-03-02",
                y: d2
            },{
                x: "2017-03-03",
                y: d3
            },...]
    },{
        topic: "hosts",
        data: [
            {
                x: "2017-03-01",
                y: e1
            },{
                x: "2017-03-02",
                y: e2
            },{
                x: "2017-03-03",
                y: e3
            },...]
    },{
        topic: "items",
        data: [
            {
                x: "2017-03-01",
                y: f1
            },{
                x: "2017-03-02",
                y: f2
            },{
                x: "2017-03-03",
                y: f3
            },...]
    },...];

我知道我必须做这样的事情:

//convert
var result = [];
for (var i=0; i<arr.length; i++) {
  result[i]=[arr[i].timemark];
}

创建数组数组:

[
    [2017-03-01],
    [2017-03-02],
    [2017-03-03]
]

几个小时之后,这是一个开始。但我找不到如何开始在数组内创建对象而不是数组的方法?试着走宝贝步骤:)

但是我在理解代码片段时遇到了问题,并且可能使用错误的语法无法使其工作。

在这种情况下,有人可以解释如何正确使用循环吗?

5 个答案:

答案 0 :(得分:2)

你可以做这样的逻辑;映射每个分组,并编译最终结果对象;

var arr = [
    {
        timemark: "2017-03-01",
        db_total: "c1",
        db_used: "d1",
        hosts: "e1",
        items: "f1"
    },{
        timemark: "2017-03-02",
        db_total: "c2",
        db_used: "d2",
        hosts: "e2",
        items: "f2"
    },{
        timemark: "2017-03-03",
        db_total: "c3",
        db_used: "d3",
        hosts: "e3",
        items: "f3"
    }];

var result = [];
Object.keys(arr[0])
      .filter(field => field != "timemark")
      .forEach(field => result.push(finalObj(field, arr.map(e => xy(e.timemark, e[field])))));

console.log(result);

function xy(x, y) {
     return { x : x, y : y };
}

function finalObj(name, arr) {
     return { topic : name, data : arr };
}

由于您建议您有更多字段,因此在最终对象中有更多topic s,如果是这种情况,我已修改,以便您添加的字段越多,它就会自动显示在最终产生的对象。 (timemark字段除外)

答案 1 :(得分:1)

您可以使用Array.prototype的{​​{3}}函数将数组中的每个元素映射到另一个元素,从而节省数组的长度。

例如:

var result = arr.map(e => ({x: e.timemark, y:db_total}));

&#13;
&#13;
var input = [{
        timemark: "2017-03-01",
        db_total: 1,
        db_used: 1,
        hosts: 1,
        items: 1
    },{
        timemark: "2017-03-02",
        db_total: 1,
        db_used: 1,
        hosts: 1,
        items: 1
    },{
        timemark: "2017-03-03",
        db_total: 1,
        db_used: 1,
        hosts: 1,
        items: 1
    }];
var output = [{
  topic:'db_total',
  data: input.map(e=> ({x:e.timemark, y:e.db_total}))
},{
  topic:'db_used',
  data: input.map(e=> ({x:e.timemark, y:e.db_used}))
},{
  topic:'hosts',
  data: input.map(e=> ({x:e.timemark, y:e.hosts}))
},{
  topic:'items',
  data: input.map(e=> ({x:e.timemark, y:e.items}))
}]
console.log(output)
&#13;
&#13;
&#13;

答案 2 :(得分:1)

&#13;
&#13;
var arr = [{
    timemark: "2017-03-01",
    db_total: 'c1',
    db_used: 'd1',
    hosts: 'e1',
    items: 'f1'
},{
    timemark: "2017-03-02",
    db_total: 'c2',
    db_used: 'd2',
    hosts: 'e2',
    items: 'f2'
},{
    timemark: "2017-03-03",
    db_total: 'c3',
    db_used: 'd3',
    hosts: 'e3',
    items: 'f3'
}];

console.log(_getConvertedArray(arr))

function _getConvertedArray(array){
    var res = [];
    array.forEach(function(obj){
        Object.keys(obj).forEach(function(key){
            res.push({
                topic: key,
                data: _getTopicData(arr, key)
            });
        });
    });

    return res;
}

function _getTopicData(array, topic){
    var res = [];

    array.forEach(function(obj){
        res.push({
            x: obj.timemark,
            y: obj[topic]
        });
    });

    return res;
}
&#13;
&#13;
&#13;

答案 3 :(得分:1)

您可以使用reduce来执行此操作

var arr = [{timemark: "2017-03-01",db_total: 'c1',db_used: 'd1',hosts: 'e1',items: 'f1'}, {timemark: "2017-03-02",db_total: 'c2',db_used: 'd2',hosts: 'e2',items: 'f2'}, {timemark: "2017-03-03",db_total: 'c3',db_used: 'd3',hosts: 'e3',items: 'f3'}];

let res = arr.reduce((a, b) => {
    for (let key in b) {
        if (b.hasOwnProperty(key) && key !== 'timemark' && ! a.find(v => v.topic === key)) {
            a.push({
                topic: key,
                data: arr.map(o => ({
                    x: o.timemark,
                    y: o[key]
                }))
            });
        }
    }
    return a;
}, []);

console.log(res);

只是为了玩地图的乐趣 - 下面会给出你想要的另一个结果集,但是依赖于你对数据的进一步使用,它可能会有所帮助(而且创建的代码也要短得多):

var arr = [{timemark: "2017-03-01",db_total: 'c1',db_used: 'd1',hosts: 'e1',items: 'f1'}, {timemark: "2017-03-02",db_total: 'c2',db_used: 'd2',hosts: 'e2',items: 'f2'}, {timemark: "2017-03-03",db_total: 'c3',db_used: 'd3',hosts: 'e3',items: 'f3'}];

let r = arr.reduce((a,b) => {
    for (let key in b) {
        if (b.hasOwnProperty(key) && key !== 'timemark')
            a.set(key, (a.get(key) || [] ).concat({x: b.timemark, y: b[key]}))
    }
    return a;
}, new Map());

console.log(r);

// USAGE 

// get the data array for db_total:
console.log(r.get("db_total"));

// or for hosts:
console.log(r.get("hosts"));

答案 4 :(得分:0)

作为一个相当简单但非常具体的函数,您可以创建一个“空”结果数组并将其填入:

var arr = [
    {
        timemark: "2017-03-01",
        db_total: 'c1',
        db_used: 'd1',
        hosts: 'e1',
        items: 'f1'
    },{
        timemark: "2017-03-02",
        db_total: 'c2',
        db_used: 'd2',
        hosts: 'e2',
        items: 'f2'
    },{
        timemark: "2017-03-03",
        db_total: 'c3',
        db_used: 'd3',
        hosts: 'e3',
        items: 'f3'
    }
];


var result = [{topic: "db_total",data: []},
              {topic: "db_used",data: []},
              {topic: "hosts",data: []},
              {topic: "items",data: []}
             ];

arr.forEach(function (obj) {
  result[0].data.push({x:obj.timemark,y: obj.db_total});
  result[1].data.push({x:obj.timemark,y: obj.db_used});
  result[2].data.push({x:obj.timemark,y: obj.hosts});
  result[3].data.push({x:obj.timemark,y: obj.items});
});

console.log(result);

或者你可以选择一种更通用的方法,它只取决于 timemark 属性,并根据提供的其他属性构建结果:

var arr = [{
  timemark: "2017-03-01",
  db_total: 'c1',
  db_used: 'd1',
  hosts: 'e1',
  items: 'f1'
}, {
  timemark: "2017-03-02",
  db_total: 'c2',
  db_used: 'd2',
  hosts: 'e2',
  items: 'f2'
}, {
  timemark: "2017-03-03",
  db_total: 'c3',
  db_used: 'd3',
  hosts: 'e3',
  items: 'f3'
}]

// Collect keys but exclude timemark
var keys = Object.keys(arr[0]).filter(function(v) {
  return v != 'timemark';
});

// Build result: loop over every object in arr
var result = arr.reduce(function(result, obj) {
  // Build object to insert into result array
  Object.keys(obj).forEach(function(p) {
    var i = keys.indexOf(p);
    // Create object for key if it's not timemark and doesn't exist
    // And push the data
    if (i != -1) {
      result[i] = result[i] || {topic:p, data:[]};
      result[i].data.push({x:obj.timemark,y:obj[p]});
    }
  })
  return result;
}, []);

console.log(result);