Reputation: 3885
[{"id":"15","heading":"Post1","content":"Post 1 Content","date":"2016-11-09 08:51:37"},
{"id":"16","heading":"Post2","content":"Post 2 Content","date":"2016-11-09 08:52:09"},
{"id":"17","heading":"Post3","content":"Post 3 Content","date":"2015-06-09 08:52:09"}]
I have above JSON array. I am trying to convert it into a JSON Object as
2016
Nov
Post1
Post2
2015
June
Post3
I was able to achieve this in PHP by
while ($row = mysqli_fetch_row($result)) {
$year = date('Y', strtotime($row['2']));
$month = date('M', strtotime($row['2']));
$navarray[$year][$month][] = array($row[0], $row[1], $row[3]);
}
But can't figure it out in JS.
Upvotes: 5
Views: 137
Reputation: 2542
following iteration will convert your structure according to PHP sample code in OP
var arr1 = [
{"id":"15","heading":"Post1","content":"Post 1 Content","date":"2016-11-09 08:51:37"},
{"id":"16","heading":"Post2","content":"Post 2 Content","date":"2016-11-09 08:52:09"},
{"id":"17","heading":"Post3","content":"Post 3 Content","date":"2015-06-09 08:52:09"}
];
var struct2 = {};
arr1.forEach(function(row) {
var date = new Date(row.date); // will extract date parts form Date object
var yyyy = date.getFullYear();
var mm = date.getMonth() + 1; // months come zero-indexed (from 0-11)
if (mm < 10) mm = '0' + mm; // left pad if needed
struct2[yyyy] = struct2[yyyy] || {}; // init if needed
struct2[yyyy][mm] = struct2[yyyy][mm] || []; // init if needed
delete row.date; // drop date if desired
struct2[yyyy][mm].push(row); // add new record
});
console.log(struct2);
/* fragment below is an extention to answer
* 2nd concern about how to iterate over this nested structure */
var panel = document.createElement('div');
document.body.appendChild(panel);
for (var year in struct2) {
for (var month in struct2[year]) {
var section = '<h2>' + year + '-' + month + '</h2>';
console.log('section: ' + section);
panel.innerHTML += section;
for (var i in struct2[year][month]) {
var item = struct2[year][month][i];
var content = '<div id="' + item.id + '">';
content += '<h3>' + item.heading + '</h3>';
content += '<p>' + item.content;
content += '</div>';
console.log('content: ' + content);
panel.innerHTML += content;
}
}
}
EDIT: extended to answer your concern about looping through the nested structure
Upvotes: 2
Reputation: 7672
You can doing loop, and for each item, check existence of current year and month, adding it if not exist yet.
var result = {};
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
var j = [{"id":"15","heading":"Post1","content":"Post 1 Content","date":"2016-11-09 08:51:37"},
{"id":"16","heading":"Post2","content":"Post 2 Content","date":"2016-11-09 08:52:09"},
{"id":"17","heading":"Post3","content":"Post 3 Content","date":"2015-06-09 08:52:09"}];
for(var i = 0; i<j.length; i++) {
var d = new Date(j[i].date);
var year = ""+d.getFullYear();
var month = months[d.getMonth()];
if(!result.hasOwnProperty(year)) {
result[year] = {};
}
if(!result[year].hasOwnProperty(month)) {
result[year][month] = [];
}
result[year][month].push(j[i].heading);
}
console.log(result);
Upvotes: 2
Reputation: 62556
Unlike PHP you must create the objects if they don't exists:
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
ar = [{"id":"15","heading":"Post1","content":"Post 1 Content","date":"2016-11-09 08:51:37"},
{"id":"16","heading":"Post2","content":"Post 2 Content","date":"2016-11-09 08:52:09"},
{"id":"17","heading":"Post3","content":"Post 3 Content","date":"2015-06-09 08:52:09"}]
obj = {}
ar.forEach(function(v) {
d = new Date(v.date);
m = monthNames[d.getMonth()]
if (!obj.hasOwnProperty(d.getFullYear())) {
obj[d.getFullYear()] = {}
}
if (!obj[d.getFullYear()].hasOwnProperty(m)) {
obj[d.getFullYear()][m] = []
}
obj[d.getFullYear()][m].push(v.heading)
})
console.log(obj)
Upvotes: 4