Brandon
Brandon

Reputation: 1617

How to sort by Year and Month in Javascript ES6

I have an array organized as such.

const array = [
  {
    Year: 2018,
    Month: 'Dec'
  },
  {
    Year: 2017,
    Month: 'Apr'
  },
  {
    Year: 2018,
    Month: 'Mar'
  },
  {
    Year: 2018,
    Month: 'Oct'
  },
  {
    Year: 2017,
    Month: 'Jan'
  },
  {
    Year: 2018,
    Month: 'Apr'
  }
]

I have successfully organized the data by Year or by Month but every time I try to organize it by both of them at once, then whichever one organized the data last will supersede everything before it. I understand why it is doing this but can't seem to find a way around it.

const sortedByYear = array.sort((a, b) => a.Year - b.Year);

Sorts by year quite simply.

const sorted = sortedByYear.sort((a, b) => Months.indexOf(a.Month) - Months.indexOf(b.Month));

Sorts by Month.

I tried to add some sort of checker in the Month checker, if the years matched then resort but that doesn't solve the problem for how it will sort.

Upvotes: 2

Views: 4297

Answers (3)

Tareq
Tareq

Reputation: 5363

You can use combination of year and month to form a comparison criteria. padStart will not work on IE so you may need a polyfill for this.

const input = [
  {
    Year: 2018,
    Month: 'Dec'
  },
  {
    Year: 2017,
    Month: 'Apr'
  },
  {
    Year: 2018,
    Month: 'Mar'
  },
  {
    Year: 2018,
    Month: 'Oct'
  },
  {
    Year: 2017,
    Month: 'Jan'
  },
  {
    Year: 2018,
    Month: 'Apr'
  }
];
const Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
input.sort((a, b) =>`${a.Year}${Months.indexOf(a.Month).toString().padStart(2,0)}` - `${b.Year}${Months.indexOf(b.Month).toString().padStart(2,0)}`
);
console.log(input);

Upvotes: 1

whyp
whyp

Reputation: 613

You can use lodash sortBy and pass the fields you want to sort by as an array.

const sorted = _.sortBy(array, ['Year', 'Month']);

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370809

You'll have to put both tests in your sort function:

const input = [
  {
    Year: 2018,
    Month: 'Dec'
  },
  {
    Year: 2017,
    Month: 'Apr'
  },
  {
    Year: 2018,
    Month: 'Mar'
  },
  {
    Year: 2018,
    Month: 'Oct'
  },
  {
    Year: 2017,
    Month: 'Jan'
  },
  {
    Year: 2018,
    Month: 'Apr'
  }
];
const Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
input.sort((a, b) => {
  if (a.Year !== b.Year) return a.Year - b.Year;
  return Months.indexOf(a.Month) - Months.indexOf(b.Month)
});
console.log(input);

Upvotes: 3

Related Questions