5
[{"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.

1
  • I will be passing the output JSON object in Underscore library. But if i could get the diff array structure it would work too. Commented Nov 9, 2016 at 3:56

3 Answers 3

4

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)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks alot! i spent more than an hour using regex expressions to parse date and making stacks and all!
Glad I could help :)
2

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

Comments

2

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

4 Comments

edited previous two variants to make only one, but if inner keys are not needed can be left out and simplify
How do i loop into this 2d array?
see extended answer
Can you have a look at this please? stackoverflow.com/questions/40501145/… :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.