A191919
A191919

Reputation: 3442

JavaScript sort items list by months

I am playing with js scripts. How to sort items of list by months. What is the best way to do it?

var dataCollection = [
        { values: { Month: { displayValue: "August" }, Sum: "10" } },
        { values: { Month: { displayValue: "February" }, Sum: "25" } },
        { values: { Month: { displayValue: "July" }, Sum: "35" } }
    ];

I expect to get

dataCollection = [
            { values: { Month: { displayValue: "February" }, Sum: "25" } },
            { values: { Month: { displayValue: "July" }, Sum: "35" } },
            { values: { Month: { displayValue: "August" }, Sum: "10" } }
        ];

Upvotes: 14

Views: 22874

Answers (3)

S_coderX451
S_coderX451

Reputation: 105

Well, there is a very simple solution to this. The above solutions are lengthy as well.

let dataCollection = [
    { values: { Month: { displayValue: "August" }, Sum: "10" } },
    { values: { Month: { displayValue: "February" }, Sum: "25" } },
    { values: { Month: { displayValue: "July" }, Sum: "35" } },
];

dataCollection.sort((a, b) => {
    return (
        new Date(`${a.values.Month.displayValue} 2022`) -
        new Date(`${b.values.Month.displayValue} 2022`)
    );
});

console.log(dataCollection);

and you get your sorted data.

Upvotes: 1

Vlad
Vlad

Reputation: 4956

Giving full credit to @blex's answer above (the accepted one), I want to expand a bit to make sure the sort method is... enhanced a bit.

// 1. Expect an array of Months, long or short format:
//      ["Jan", "Mar", "Feb"] or ["January", "march", "FEBRUARY"] 
// 2. Support optional reverse sorting.
// 3. Ensure SAFE sorting (does not modify the original array).
function sortByMonthName(monthNames, isReverse = false) {
  const referenceMonthNames = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];
  const directionFactor = isReverse ? -1 : 1;
  const comparator = (a, b) => {
    if (!a && !b) return 0;
    if (!a && b) return -1 * directionFactor;
    if (a && !b) return 1 * directionFactor;

    const comparableA = a.toLowerCase().substring(0, 3);
    const comparableB = b.toLowerCase().substring(0, 3);
    const comparisonResult = referenceMonthNames.indexOf(comparableA) - referenceMonthNames.indexOf(comparableB);
    return comparisonResult * directionFactor;
  };
  const safeCopyMonthNames = [...monthNames];
  safeCopyMonthNames.sort(comparator);
  return safeCopyMonthNames;
}

// Examples:
const dataset = ["Mar", "January", "DECEMBER", "february"];
const test1 = sortByMonthName(dataset);
const test2 = sortByMonthName(dataset, true);

Upvotes: 0

blex
blex

Reputation: 25634

You can do it by having a list of all the months in the right order, and sorting your array based on them:

var dataCollection = [
  { values: { Month: { displayValue: "August" }, Sum: "10" } },
  { values: { Month: { displayValue: "February" }, Sum: "25" } },
  { values: { Month: { displayValue: "July" }, Sum: "35" } }
];

sortByMonth(dataCollection);

console.log(dataCollection);

function sortByMonth(arr) {
  var months = ["January", "February", "March", "April", "May", "June",
  	        "July", "August", "September", "October", "November", "December"];
  arr.sort(function(a, b){
      return months.indexOf(a.values.Month.displayValue)
           - months.indexOf(b.values.Month.displayValue);
  });
}

Upvotes: 34

Related Questions