Creatz
Creatz

Reputation: 61

Sort array by current date

I am looking to sort the values in an array based on the current date.

My values :

[{
  date: "12-28",
  id: 1
}, {
  date: "11-30",
  id: 2
}, {
  date: "09-30",
  id: 3
}, {
  date: "05-30",
  id: 4
}]

I tried to do something like this, but it doesn't really work :

var array = [{id: 1, date:'12-28'}, 
{id: 2, date:'11-30'}, 
{id: 3, date:'09-30'}, 
{id: 4, date:'05-30'}];

const now = Date.now();

array.sort(function(a, b) {     
    var c = new Date(a.date);
    var d = new Date(b.date);
    return (now-c)-(now-d);
});

console.log(array);

If it's November 29th :

[{
  date: "11-30",
  id: 2
}, {
  date: "12-28",
  id: 1
}, {
  date: "05-30",
  id: 4
}, {
  date: "09-30",
  id: 3
}]

Upvotes: 0

Views: 419

Answers (2)

PeterKA
PeterKA

Reputation: 24638

How about turning mm-dd to mmdd and then converting to number and then using Math.abs() as follows?

const arr = [
    {date: "12-28",id: 1}, 
    {date: "11-30",id: 2}, 
    {date: "09-30",id: 3}, 
    {date: "05-30",id: 4}
];

const dt = new Date();
const now = +[dt.getMonth()+1, dt.getDate()].map(v => `0${v}`.slice(-2)).join('');

const ordered = arr.sort((a,b) => Math.abs(+a.date.replace(/[^\d]+/,'') - now) - Math.abs(+b.date.replace(/[^\d]+/,'') - now));

console.log( ordered );

All Dates Future

If all dates are to be considered to be present or future, here is a concept we can employ:

const arr = [
    {date: "12-28",id: 1}, 
    {date: "11-30",id: 2}, 
    {date: "09-30",id: 3}, 
    {date: "05-30",id: 4}
];

//converts m-d to mm-dd
const fmt = md => md.split('-').map(p => `0${p}`.slice(-2)).join('-');
const now = new Date();
const year = new Date().getFullYear();
const nww = fmt(`${now.getMonth()+1}-${now.getDate()}`);
const nw = new Date(`${year}-${nww}`).getTime();

const ordered = arr.map(({
    date: d,
    id
}) => ({
    date: d,
    id,
    d: `${d < nww ? (year + 1) : year}-${d}`
})).map(({
    d,
    ...rest
}) => ({
    ...rest,
    d,
    ...{
        t: new Date(d).getTime()
    }
})).sort((a, b) => (a.t - nw) - (b.t - nw)).map(({
    date,
    id
}) => ({
    date,
    id
}));

console.log( ordered );

Upvotes: 1

Terry Lennox
Terry Lennox

Reputation: 30685

You can use Array.sort() to give you the desired result, I've moved the dates in the input array to this year:

let input = [{ date: "2021-12-28", id: 1 }, { date: "2021-11-30", id: 2 }, { date: "2021-09-30", id: 3 }, { date: "2021-05-30", id: 4 }];

function sortByNearest({ date: a}, {date: b}) {
    const now = Date.now();
    return (Math.abs(Date.parse(a) - now)) - (Math.abs(Date.parse(b) - now));
}

console.log(input.sort(sortByNearest))
    
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Related Questions