Reputation: 827
I have the following data :
[
{"date":1900,"data":[
{"name":"Blackbird","value":0},
{"name":"Seagull","value":1},
{"name":"Sparrow","value":0}
]},
{"date":1910,"data":[
{"name":"Owl","value":1}
]},
{"date":1920,"data":[
{"name":"Eagle","value":0},
{"name":"Albatross","value":2}
]}
]
I need to make an incremental array of arrays from it. It should look something like this :
[
[
{"name":"Blackbird","value":0,"date":1900},
{"name":"Seagull","value":1,"date":1900},
{"name":"Sparrow","value":0,"date":1900}
],
[
{"name":"Blackbird","value":0,"date":1910},
{"name":"Seagull","value":1,"date":1910},
{"name":"Sparrow","value":0,"date":1910},
{"name":"Owl","value":1,"date":1910}
],
[
{"name":"Blackbird","value":0,"date":1920},
{"name":"Seagull","value":1,"date":1920},
{"name":"Sparrow","value":0,"date":1920},
{"name":"Owl","value":1,"date":1920},
{"name":"Eagle","value":0,"date":1920},
{"name":"Albatross","value":2,"date":1920}
]
]
No matter what I have tried, I always end up with all the dates I add to the objects being equal to the last value (1920 here). I understand that the objects are copied by reference only. I have tried using array.map() (like in the answer given here, but my question was not formulated right), but I still get the same problem.
EDIT Here's one example of code I've tried :
var temp = [];
var b = data.map(function(c, index, main) {
var year = c.date;
temp = [];
main.slice(0, index + 1).map(function(d){
var t = d.data.map(function(e){
e.date = year;
return e;
});
temp = temp.concat(t);
});
return temp;
});
console.log(b);
Upvotes: 2
Views: 65
Reputation: 318162
Use map, iterate over the inner array, and set the date
property to each object etc.
var data = [
{"date":1900,"data":[
{"name":"Blackbird","value":0},
{"name":"Seagull","value":1},
{"name":"Sparrow","value":0}
]},
{"date":1910,"data":[
{"name":"Owl","value":1}
]},
{"date":1920,"data":[
{"name":"Eagle","value":0},
{"name":"Albatross","value":2}
]}
]
data = data.map(function(obj, i, arr) {
var o = [];
arr.slice(0, i).forEach(function(item) {
item.data.forEach(function(data) {
o.push(Object.assign({}, data))
});
});
return o.concat(obj.data.map(function(item) { item.date = obj.date; return item }));
});
document.body.innerHTML = '<pre>' + JSON.stringify(data, null, 4) + '</pre>';
Upvotes: 0
Reputation: 40374
Here's a working example:
You need to clone the object in order to "break" the reference.
var data = [
{
"date":1900,
"data":[
{"name":"Blackbird","value":0},
{"name":"Seagull","value":1},
{"name":"Sparrow","value":0}
]
},
{
"date":1910,
"data":[
{"name":"Owl","value":1}
]
},
{
"date":1920,
"data":[
{"name":"Eagle","value":0},
{"name":"Albatross","value":2}
]
}
];
var incremental = [];
var dataHistory = null;
for(i = 0; i < data.length; i++){
var temp = dataHistory ? dataHistory.slice() : []; //.slice to clone array
//Replace all values with current date.
for(var j = 0; j < temp.length; j++){
temp[j] = JSON.parse(JSON.stringify(temp[j])); //Clone object
temp[j].date = data[i].date;
}
//Add current date to object.
for(var j = 0; j < data[i].data.length; j++){
var aux = {
name: data[i].data[j].name,
value: data[i].data[j].value,
date: data[i].date
};
temp.push(aux);
}
dataHistory = temp;
incremental.push(temp);
}
document.body.innerHTML = '<pre>' + JSON.stringify(incremental, null, 4) + '</pre>';
If you're using jQuery you can replace:
temp[j] = JSON.parse(JSON.stringify(temp[j]));
With:
temp[j] = $.extend({}, temp[j]);
Upvotes: 1
Reputation: 1
Try this one:
var data = [
{"date":1900,"data":[
{"name":"Blackbird","value":0},
{"name":"Seagull","value":1},
{"name":"Sparrow","value":0}
]},
{"date":1910,"data":[
{"name":"Owl","value":1}
]},
{"date":1920,"data":[
{"name":"Eagle","value":0},
{"name":"Albatross","value":2}
]}
];
var result = data.map(function(item) {
var replacement = [];
for (var key in item.data) {
var subItem = item.data[key];
subItem.date = item.date;
replacement.push(subItem);
}
return replacement;
});
document.body.innerHTML = '<pre>' + JSON.stringify(result, null, 3) + '</pre>';
Upvotes: 0