0

hey I've json that look like this

news
    {
        title: 'hello world',
        body: 'bla bla bla',
        publish_date: '2014-04-12'
    },
    {
        title: 'hello world',
        body: 'bla bla bla',
        publish_date: '2014-04-30'
    }   
    {
        title: 'hello world 2',
        body: 'bla bla bla',
        publish_date: '2015-02-30'
    },
    {
        title: 'hello world 2',
        body: 'bla bla bla',
        publish_date: '2015-02-17'
    },
    {
        title: 'hello world 2',
        body: 'bla bla bla',
        publish_date: '2015-05-30'
    }

and I'd like to sort it by the 'publish_date' per 'years' and then per 'months' to be looking like this:

{
    2014: [{
        04: [{
            {
                title: 'hello world',
                body: 'bla bla bla',
                publish_date: '2014-04-12'
            },
            {
                title: 'hello world',
                body: 'bla bla bla',
                publish_date: '2014-04-30'
            }   
        }]
    ]}
    2015: [{
        02: [{
            {
                title: 'hello world 2',
                body: 'bla bla bla',
                publish_date: '2015-02-30'
            },
            {
                title: 'hello world 2',
                body: 'bla bla bla',
                publish_date: '2015-02-17'
            },
        }],
        05: [{
            {
                title: 'hello world 2',
                body: 'bla bla bla',
                publish_date: '2015-05-30'
            }
        ]}
    }]
}

so I found this sort JSON by date to sort my json by dates, and after that I got this http://lodash.com/docs#forEach to run over my main json but how do I "split" the date so I can make it done ? split it into years and then month ? and how do I "push" into my new sorted json ? how can I make sure to not miss any month in every year ? a direction or anyway to make it done would be awesome :)

thank you verymuch!

Community
  • 1
  • 1
greW
  • 1,248
  • 3
  • 24
  • 49

4 Answers4

1

you want to reduce in this case. To split the date you could parse it with Date and get the year and moth from it. in your map callback you can then add the value depending on that to the right thing.

i.e.

    var myRes = _.reduce(arr, function(result, elem, key) {
      // get the year and month strings
      var year = getYearFromDateString(elem.publish_date)
      var month = getMonthFromDateString(elem.publish_date)
      // check and initiallize the object structure
      if (result[year] == null) result[year] = {}
      if (result[year][month] == null) result[year][month] = []
      result[year][month].push(elem)
      return result
    }, {} /*this is the initially empty object, the result */)
greelgorke
  • 364
  • 1
  • 5
  • can u explain some more about how shall I do it with reduce ? i got to split the date with `.split("-")` but I cant see how reduce help me here, thanks! – greW Apr 25 '14 at 09:10
1

Probably best to convert those dates into actual date objects then it's easier and clearer to access the years and months as shown here: http://jsfiddle.net/RAkkk/

I used native forEach for brevity but Lodash can do the same.

var json = [
{
    title: 'hello world',
    body: 'bla bla bla',
    publish_date: '2014-04-12'
},
{
    title: 'hello world',
    body: 'bla bla bla',
    publish_date: '2014-04-30'
},   
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-02-30'
},
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-02-17'
},
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-05-30'
}
];

var newJson = {};

json.forEach(function (item) {
    var date = new Date(item.publish_date),
        year = date.getUTCFullYear(),
        month = date.getUTCMonth() + 1;

    newJson[year] = newJson[year] || {};
    newJson[year][month] = newJson[year][month] || [];
    newJson[year][month].push(item);
});

console.log(newJson);

Then it's reasonably straight forward to assert their existence in the target object and either create and push or simply push, as shown in the fiddle.

Also if you wanted to actually sort a month group array you can compare dates like so:

var a = new Date('2015-02-17');
var b = new Date('2015-05-30');
console.log(a < b);
Mattyod
  • 1,349
  • 1
  • 9
  • 12
  • Perfect! thank you very much! I just have a question is that || stands for ? `newJson[year] = newJson[year] **||** {};` I know its an operator for "OR" but what it does here? its like if ? true : false ? please explain :) thanks! – greW Apr 25 '14 at 09:55
  • 1
    @greW - it's assigning an empty object to newJson[year] if it doesn't already exist (and leaves it unchanged if it does already exist). Otherwise, the next two lines would produce undefined errors. Sort of the same deal in the subsequent line that creates an initially empty array for `newJson[year][month]` if it isn't already set up. – barry-johnson Apr 25 '14 at 17:13
0

Loop through the original json:

var newJson = [];
for (var i in originalJson) {
    var year = originalJson[i].publish_date.substring(0,4);
    var month = originalJson[i].publish_date.substring(5,2);
    if (typeof newJson[year] == "undefined") newJson[year] = [];
    if (typeof newJson[year][month] == "undefined") newJson[year][month] = [];
    newJson[year][month].push(originalJson[i]);
}

I did not tried this.. but maybe works :D

MSzucs
  • 178
  • 1
  • 10
  • well, I tried this, more like: pastebin.com/ezezNwME and all I get is a lot of: , , , , , , , [ ] ] not sure, why .. I trid to replace mynew = []; to mynew = {}; and then I get: { '2014': [ ] } { '2014': [ ], '2015': [ ] } thanks for you'r answer! – – greW Apr 25 '14 at 09:23
0
function custom_sort(a, b) {
    return new Date(a.publish_date).getTime() - new Date(b.publish_date).getTime();
}
var json = [
{
    title: 'hello world',
    body: 'bla bla bla',
    publish_date: '2014-04-12'
},
{
    title: 'hello world',
    body: 'bla bla bla',
    publish_date: '2014-04-30'
},   
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-02-30'
},
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-02-17'
},
{
    title: 'hello world 2',
    body: 'bla bla bla',
    publish_date: '2015-05-30'
}
];

json .sort(custom_sort);
Tuhin
  • 3,335
  • 2
  • 16
  • 27