2017-03-03 77 views
1

我有对象的数组:Array对象的含有阵列对象的阵列

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 
    },..] 

我struglling如何将其变换到另一个数组但具有不同的结构:

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] 
] 

这是几个小时后的开始。但我找不到一个方法如何开始在数组内创建对象而不是数组?试图去婴儿的步骤:)

但我真的有问题的理解片段,并可能使用错误的语法不能让它的工作。

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

回答

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进入决赛的对象,如果是这样的话,我已经修改,让你添加更多的字段,它会自动显示在最终的结果对象中。(除timemark场OFC)

+0

太棒了!你能解释你在哪里使用函数xy()?我基本上有点了解其他所有的东西:) – user2917823

+0

它在'arr'的映射中,只是不想在算法部分使用这种硬编码:)但是,如果你愿意,你可以将它们移动到那里像 –

+0

我看到的唯一问题是,你没有防范对象的继承的枚举属性。类似于Object.keys(arr [0])。reduce(...,[])'会解决这个问题并一次性创建结果数组。否则,非常优雅。 – RobG

1

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

例如:

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

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)

+0

只注意到我看错你了换货什么,秒编辑我的答案。 –

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' 
 
}]; 
 

 
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; 
 
}

+3

为什么要使用小提琴?只需将其作为可运行代码片段发布即可。 – RobG

+0

我还挺新的^^得编辑我的答案 – Paul

1

您可以用减少做

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);

只是为了与地图玩的乐趣 - 下面将给出另一个结果集,作为您的预期,但dependending关于进一步使用您的数据,这可能会有所帮助(并且创建代码也更短):

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"));

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);

或者你可以去一个更一般方法只取决于时间戳属性,并根据提供的任何其他属性构建结果:

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);