0

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
}]
7
  • Can you add an example of the output you are wanting the data in? Commented Nov 29, 2021 at 19:13
  • You want to sort them by how close they are to the current date? If so then 2000-12-28 will be the closest to 2021-11-29. Commented Nov 29, 2021 at 19:17
  • Hello, I mainly want to sort by month and day, the year doesn't really matter to me Commented Nov 29, 2021 at 20:53
  • I dont understand your ordering based on your output if sorting by Nov 29th. Are you trying to put any dates after Nov 29th first and then any dates before last? Commented Nov 29, 2021 at 21:17
  • Let me try to put it another way. Let's say that each date is a birthday. I want to be able to display the next birthdays based on the current date. If it's November 29th, the next birthdays are : 11-30 , 12-28, 05-30, 09-30 Commented Nov 29, 2021 at 21:55

2 Answers 2

1

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 );

Sign up to request clarification or add additional context in comments.

7 Comments

Hello, Thank you very much for your help. However, this is not quite the result I want. The result should be in this order: 11-30 , 12-28, 05-30, 09-30
...next birthdays based on the current date... So you want to take all the dates as being in the future? That changes everything; will take a look shortly.
That's exactly it, and I know it's not a simple thing to do ;)
Check out the second option that takes much of the processing away from the sort function.
That's exactly it! It's really perfect! A huge thank you!
|
0

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; }

3 Comments

Thank you very much for your answer. Nevertheless, the result is not exactly correct. Indeed, the ids should be in this order: 2, 1, 4, 3 (2021-11-30, 2021-12-28, 2021-05-30, 2021-09-30)
Oh cool, I'm just not sure why 2021-05-30 has a higher sort order than 2021-09-30. Could you explain this? Thanks!
Indeed, I understand that my request is not very logical. In fact, the year is not really necessary, I mainly want to sort by months and days. I've modified my question, hoping that it will be a bit clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.