Reputation: 199
I've got an array of 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
},..]
I am struglling how to transform it to another array but with different structure:
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
},...]
},...];
I know I have to do something like this:
//convert
var result = [];
for (var i=0; i<arr.length; i++) {
result[i]=[arr[i].timemark];
}
Which creates array of arrays:
[
[2017-03-01],
[2017-03-02],
[2017-03-03]
]
It is kinda a start after some hours. But I can't find a way how to start creating objects inside the array instead of arrays? Trying to go baby steps :)
but I am really having problems understanding the snippet and probably using wrong syntax can't get it to work.
Could someone explain how to properly use loop in this case?
Upvotes: 1
Views: 472
Reputation: 106
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;
}
Upvotes: 1
Reputation: 4214
You can use the Array.prototype
's map function to map each element from the array to a different one, conserving the length of the array.
ex:
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)
Upvotes: 1
Reputation: 14678
You can do such a logic; mapping for each grouping, and compiling the final result object;
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 };
}
Since you were suggesting you'd have more fields, thus more topic
s in the final object, if that is the case, I have modified so that the more fields you add, it will automatically show up in the final resulting object. (Except timemark
field ofc)
Upvotes: 2
Reputation: 73211
You can use reduce to do that
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);
Just for the fun of playing with Maps - below would give another resultset as you intended, but dependending on the further use of your data, it might be helpful (and the code for the creation is also much shorter):
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"));
Upvotes: 1
Reputation: 147343
As a fairly simple but very specific function, you can create an "empty" result array and fill it in:
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);
Or you could go for a more general approach that only depends on the timemark property and builds a result from whatever other properties are provided:
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);
Upvotes: 0