0

Start string

let current dates'01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026,09/08/2027'

I need to convert to and array of strings sorted by year:

let closureDates = ['01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021','01/02/2022,01/03/2022,11/23/2022','09/08/2023,12/24/2023','11/22/2024','01/02/2025','01/03/2026','09/08/2027',
destructClosureDates(closureDatesMultpleYrs)

function destructClosureDates(dates) {
    let strDates = dates.split(",")
    let strDays = []
    let strYears = []
    strDates.forEach(day => {
        strDays.push(day.split('/'))
    })
    strDays.forEach(day => {
        strYears.push(day[2])
    })

    let sortedDates = strDates.sort((a, b) => {
        a = a.split('/')
        b = b.split('/')

        return a[2].localeCompare(b[2]);
    })

    let unqiYears = [...new Set(strYears)]
    let sortedUniYears = unqiYears.sort((a, b) => {
        return a.localeCompare(b)
    })
}

    const Lmap = new Map(Object.entries(newArr));

I'm not sure how to loop through the Map and combine the dates strings by year. Do I need to restructure the code in another data structure?

3 Answers3

1

You can achieve this with a single reduce() call accumulating into an object using the year as key. This allows you to avoid an explicit sort() call by leveraging the fact that integer object properties are implicitly sorted (see: Does JavaScript guarantee object property order?).

const
  currentDates = '09/08/2027,01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026',

  closureDates = Object
    .values(
      currentDates
        .split(',')
        .reduce((a, date) => {
          const [, , year] = date.split('/');
          a[year] = (year in a) ? `${a[year]},${date}` : date;
          return a;
        }, {})
    );

console.log(closureDates);
pilchard
  • 12,414
  • 5
  • 11
  • 23
0

Split to each date by "," then sort it by split date by "/" take last value and sort by it then just join it.

const dates = '01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026,09/08/2027'

const sorted = dates
  .split(",")
  .sort((a,b) => +a.split("/")[2] - +b.split("/")[2])
  .join(",")

console.log(sorted)

or comparing full date object (sorted decreasing)

const dates = '01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026,09/08/2027'

const sorted = dates
  .split(",")
  .sort((a,b) => new Date(b).getTime() - new Date(a).getTime())
  .join(",")

console.log(sorted)
Robert
  • 2,538
  • 1
  • 9
  • 17
0

Use String.split() to create an array of text dates.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split

Then using Array.sort(), you can just convert the dates from text to a new Date() for the sorting purpose.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Bonus

You can also use Array.filter() to pull out any specific value.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

See snippet where the descending array is also filtered on the year 2021.

const currentdates = `01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026,09/08/2027`;

const sortedAsc = [currentdates
  .split(`,`)
  .sort((a, b) => new Date(a) - new Date(b))
  .join(`,`)
];

const sortedDesc = [currentdates
  .split(`,`)
  .sort((a, b) => new Date(b) - new Date(a))
  .filter(elem => new Date(elem).getFullYear() == 2021)
  .join(`,`)
];



document.write("<h4>Ascending:</h4><br><code>");
document.write(JSON.stringify(sortedAsc, null, 2));

document.write("</code><br><br><h4>Descending and Filtered on the year 2021:</h4><br><code>");
document.write(JSON.stringify(sortedDesc, null, 2));
document.write("</code>");

EDIT

I just read your post again and realized that I didn't scroll your intended results to see that you would like an array with the dates as strings grouped by years.

After creating the array of dates, using the Array.reduce() method, you can grab the year from each date using new Date(elem).getFullYear(), and add them to a new Set(). Since a Set won't allow duplicates, you get a unique list of years.

You can then use Set.forEach() to loop through all of the years and filter the dateArray by each year, and use Array.join() on the filtered array to create a string of dates. You can then Array.push() the filtered array to the closureDates array.

updated snippet below:

const currentdates = `01/02/2021,09/08/2021,11/22/2021,11/23/2021,12/24/2021,01/02/2022,01/03/2022,09/08/2023,11/22/2024,11/23/2022,12/24/2023,01/02/2025,01/03/2026,09/08/2027`;

const closureDates = [];

const dateArray = currentdates.split(`,`);
const years = dateArray.reduce((a, c) => a.add(new Date(c).getFullYear()), new Set);

years.forEach( y => {
  const filtered = dateArray.filter( el => new Date(el).getFullYear() === y).join(`,`);
  closureDates.push(filtered);
});

document.write(`<pre>${JSON.stringify(closureDates, null, 2)}</pre>`);
Steve
  • 878
  • 1
  • 5
  • 9