Home > Enterprise >  (javascript) How to sort an array of strings that has seasons and years?
(javascript) How to sort an array of strings that has seasons and years?

Time:05-23

The seasons need to be in this order: Spring, Summer, Fall, Winter and each season has the year 2025 and 2026.

All the 2025's need to be with each other and all the 2026's need to be with each other (2025 and 2026 are just examples the years can be anything: 1945, 3005, 7980, etc).

for example:

const seasonArr = ['Spring2026',' Spring2025','Summer2026','Summer2025','Fall2025','Fall2026','Winter2026','Winter2025']

let sortedArr = []

const someFunction = () => {
   ...
}

someFunction(seasonArr) // output: sortedArr = ['Spring2025', 'Summer2025', 'Fall2025', 'Winter2025', 'Spring2026', 'Summer2026', 'Fall2026', 'Winter2026']

I know I probably have to compare the years but since they're strings I'm struggling to compare just the numbers.

this is something that I thought of:

const seasonArr = ['Spring2026',' Spring2025','Summer2026','Summer2025','Fall2025','Fall2026','Winter2026','Winter2025']

let sortedArr = []

const someFunction = (seasonArr) => {
   for (const season of seasonArr) {
     let year = season.split(/([0-9] )/)
     // unsure where to go from here
   }
}

someFunction(seasonArr)

CodePudding user response:

I split the strings into year and season, compare the year and compare the season for same years. I use an array of seasons for the order.

const seasonArr = ['Spring2026','Spring2025','Summer2026','Summer2025','Fall2025','Fall2026','Winter2026','Winter2025'];

const seasons = ['Spring', 'Summer', 'Fall', 'Winter'];

const regexp = /(. )(\d{4})/;
const someFunction = (s) => {
   return [...s].sort((lhs, rhs) => {
     const [seasonL, yearL] = regexp.exec(lhs).slice(1);
     const [seasonR, yearR] = regexp.exec(rhs).slice(1);
     return  yearL -  yearR || seasons.indexOf(seasonL) - seasons.indexOf(seasonR);
   });
}

let sortedArr = someFunction(seasonArr);
console.log(sortedArr);

I create a shallow copy with

[...s]

to keep the original array unchanged.

Same logic with better performance for large arrays

const seasonArr = ['Spring2026','Spring2025','Summer2026','Summer2025','Fall2025','Fall2026','Winter2026','Winter2025'];

const seasons = ['Spring', 'Summer', 'Fall', 'Winter'];

const regexp = /(. )(\d{4})/;
const someFunction = (s) => {
   return s
     .map(el => {
       const [season, year] = regexp.exec(el).slice(1);
       return [season, year, seasons.indexOf(season[0])];
     })
     .sort((lhs, rhs) => {
       return  lhs[1] -  rhs[1] || lhs[2] - rhs[2];
     })
     .map(el => el[0]   el[1]);
}

let sortedArr = someFunction(seasonArr);
console.log(sortedArr);

CodePudding user response:

This solution builds on basically what you're suggesting.

First, split the values into an array of objects that have season and year. Then sort by year and the index of the season. Then put the values back together.


const seasonArr = ['Spring2026',' Spring2025','Summer2026','Summer2025','Fall2025','Fall2026','Winter2026','Winter2025']

const SEASONS = ["Spring", "Summer", "Fall", "Winter"]

function comparator(a, b) {
  if (a.year == b.year) {
    const aSeasonIndex = SEASONS.indexOf(a.season)
    const bSeasonIndex = SEASONS.indexOf(b.season)
    return aSeasonIndex - bSeasonIndex;
  }
  return a.year - b.year;
}

function seasonYearToObject(obj) {
  const matches = obj.match(/([^\d]*)(\d )/)
  if (matches) {
    return {season: matches[1], year: matches[2]}
  }
}

function objectToSeasonYear(obj) {
  return `${obj.season}${obj.year}`
}
  
function sortByYearAndSeason(arr) {
  return arr
    .map(entry => seasonYearToObject(entry))
    .sort(comparator)
    .map(objectToSeasonYear);
}

console.log (sortByYearAndSeason(seasonArr))

  • Related