Home > Enterprise >  How to sort javascript's array of objects by multiple property value
How to sort javascript's array of objects by multiple property value

Time:07-27

I have an array of Objects that contains the fYear and FQtr keys. My goal is to sort by FQtr keys and fYear. Would you please help?

Original Data

const data = [
    { "fYear": "FY22 Q3", "FQtr": "W10"},
    { "fYear": "FY22 Q3", "FQtr": "W11"},
    { "fYear": "FY22 Q3", "FQtr": "W12"},
    { "fYear": "FY22 Q3", "FQtr": "W13"},
    { "fYear": "FY22 Q3", "FQtr": "W2"},
    { "fYear": "FY22 Q4", "FQtr": "W1"},
    { "fYear": "FY22 Q3", "FQtr": "W3"},
    { "fYear": "FY22 Q3", "FQtr": "W4"},
    { "fYear": "FY22 Q4", "FQtr": "W2"},
    { "fYear": "FY22 Q3", "FQtr": "W5"},
    { "fYear": "FY22 Q3", "FQtr": "W6"},
    { "fYear": "FY22 Q3", "FQtr": "W7"},
    { "fYear": "FY22 Q3", "FQtr": "W8"},
    { "fYear": "FY22 Q3", "FQtr": "W9"},
    { "fYear": "FY22 Q4", "FQtr": "W4"},
    { "fYear": "QTD", "FQtr": "QTD"},
    { "fYear": "FY22 Q4", "FQtr": "W3"}
]

Expected Sorted Data


const data = [
    { "fYear": "FY22 Q3", "FQtr": "W2"},
    { "fYear": "FY22 Q3", "FQtr": "W3"},
    { "fYear": "FY22 Q3", "FQtr": "W4"},
    { "fYear": "FY22 Q3", "FQtr": "W5"},
    { "fYear": "FY22 Q3", "FQtr": "W6"},
    { "fYear": "FY22 Q3", "FQtr": "W7"},
    { "fYear": "FY22 Q3", "FQtr": "W8"},
    { "fYear": "FY22 Q3", "FQtr": "W9"},
    { "fYear": "FY22 Q3", "FQtr": "W10"},
    { "fYear": "FY22 Q3", "FQtr": "W11"},
    { "fYear": "FY22 Q3", "FQtr": "W12"},
    { "fYear": "FY22 Q3", "FQtr": "W13"},
    { "fYear": "FY22 Q4", "FQtr": "W1"},
    { "fYear": "FY22 Q4", "FQtr": "W2"},
    { "fYear": "FY22 Q4", "FQtr": "W3"},
    { "fYear": "FY22 Q4", "FQtr": "W4"},
    { "fYear": "QTD", "FQtr": "QTD"}
]

My Approach

function sortFQtr( a, b ) {
    const [prevVal, nextVal] = [Number.parseInt(a.FQtr.substring(1)), Number.parseInt(b.FQtr.substring(1))];
  if ( prevVal < nextVal ) return -1;
  if ( prevVal > nextVal) return 1;
  return 0;
}

// ["FY22 Q4", "FY22 Q3", "QTD"]
 var fYears = data.map(value => value.fYear).filter( (value, index, _arr) => _arr.indexOf(value) == index);

CodePudding user response:

Put everything inside the .sort callback. While you're comparing the FQtrs properly, you also need to factor in the fYear values in the same function.

localeCompare will make this easy - lexiographically, FY22 Q3 is followed by FY22 Q4, which is then followed by QTD. Sort by that difference - and if there is no difference, then sort by the FQtr property, which can also be done with localeCompare (with the numeric option).

const data = [
    { "fYear": "FY22 Q3", "FQtr": "W10"},
    { "fYear": "FY22 Q3", "FQtr": "W11"},
    { "fYear": "FY22 Q3", "FQtr": "W12"},
    { "fYear": "FY22 Q3", "FQtr": "W13"},
    { "fYear": "FY22 Q3", "FQtr": "W2"},
    { "fYear": "FY22 Q4", "FQtr": "W1"},
    { "fYear": "FY22 Q3", "FQtr": "W3"},
    { "fYear": "FY22 Q3", "FQtr": "W4"},
    { "fYear": "FY22 Q4", "FQtr": "W2"},
    { "fYear": "FY22 Q3", "FQtr": "W5"},
    { "fYear": "FY22 Q3", "FQtr": "W6"},
    { "fYear": "FY22 Q3", "FQtr": "W7"},
    { "fYear": "FY22 Q3", "FQtr": "W8"},
    { "fYear": "FY22 Q3", "FQtr": "W9"},
    { "fYear": "FY22 Q4", "FQtr": "W4"},
    { "fYear": "QTD", "FQtr": "QTD"},
    { "fYear": "FY22 Q4", "FQtr": "W3"}
];

data.sort((a, b) => (
  a.fYear.localeCompare(b.fYear)
  || a.FQtr.localeCompare(b.FQtr, 'en', { numeric: true })
));
console.log(data);

  • Related