Mojo
Mojo

Reputation: 518

Sort an array of object on month basis

I am working with the dashboard and I have a chart in which I have to show count against month label. I have an array of objects with count and month Key. I want to sort this array of objects in Ascending order with month key value. I tried below code works fine in chrome but array does on get sorted in Firefox.

var xAxis =  [
{count: 0, month: "Jan 2019"},
{count: 7, month: "Dec 2019"},
{count: 0, month: "Feb 2019"},
{count: 0, month: "Jul 2019"}
] 

 xAxis.sort(function(a, b) {
  var c = new Date(a.month);
  console.log("TCL: CountByUserGraph -> makeApiCall -> c", c)
  // Chrome showing  ==> Tue Jan 01 2019 00:00:00 GMT+0530 
  //firefox showing  ==> Invalid Date
  var d = new Date(b.month);
  return c - d;
});

Upvotes: 1

Views: 1170

Answers (4)

Bad Dobby
Bad Dobby

Reputation: 871

The following implementation compares the year as well as month -

const sortByMonth = arr => {
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
  const getIndexOfMonth = month => months.indexOf(month)
  return [ ...arr ].sort((left, right) => {
    const [ leftMonth, leftYear ] = left.month.split(' ')
    const [ rightMonth, rightYear ] = right.month.split(' ')
    if (leftYear !== rightYear) {
      return parseInt(leftYear) - parseInt(rightYear)
    }
    return getIndexOfMonth(leftMonth) - getIndexOfMonth(rightMonth)
  })
}

var xAxis =  [
  {count: 0, month: "Jan 2019"},
  {count: 7, month: "Dec 2019"},
  {count: 0, month: "Dec 2017"},
  {count: 0, month: "Jun 2018"},
  {count: 0, month: "Feb 2019"},
  {count: 0, month: "Jul 2019"},
];

console.log(sortByMonth(xAxis))

Upvotes: 3

Tân
Tân

Reputation: 1

You can create an array which contains all of the short names of the months. Then, splitting the string in your input to get the short name of the month, and comparing it with the items in the array.

var months = ['Jan', 'Feb', 'Mar', 'Apr', 
              'May', 'June', 'Jul', 'Aug', 
              'Sept', 'Oct', 'Nov', 'Dec'];

var xAxis =  [
{count: 0, month: "Jan 2019"},
{count: 7, month: "Dec 2019"},
{count: 0, month: "Feb 2019"},
{count: 0, month: "Jul 2019"}
];

var output = xAxis.sort(function (a, b) { 
    return months.indexOf(a.month.substr(0, 3)) - months.indexOf(b.month.substr(0, 3)) 
});

console.log(output);

Upvotes: 2

TKoL
TKoL

Reputation: 13902

You made a typo. Let me show you:

var xAxis =  [
{count: 0, month: "Jan 2019"},
{count: 7, month: "Dec 2019"},
{count: 0, month: "Feb 2019"},
{count: 0, month: "Jul 2019"}
] 

 xAxis.sort(function(a, b) {
  var c = new Date(a.month);
  // console.log("TCL: CountByUserGraph -> makeApiCall -> c", c)
  // Chrome showing  ==> Tue Jan 01 2019 00:00:00 GMT+0530 
  //firefox showing  ==> Invalid Date
  var d = new Date(b.month);
  return c - d;
});

console.log(xAxis);

the typo line was var d = .... You were setting both dates to the a value

[edit] please note: the code I posted above works in Chrome, but a user Alexander posted below that the same code will not work in every browser.

Upvotes: 1

Alexander van Oostenrijk
Alexander van Oostenrijk

Reputation: 4774

Firefox's Date implementation cannot parse strings in MMM YYYY format like the ones in your example. Consider using a different format. If you must use this format, consider using a library that allows you to parse these dates across browsers like Momentjs or date-fns.

Upvotes: 1

Related Questions