【问题标题】:Sort array by current date按当前日期对数组进行排序
【发布时间】:2022-01-06 14:48:20
【问题描述】:

我希望根据当前日期对数组中的值进行排序。

我的价值观:

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

我试图做这样的事情,但它并没有真正起作用:

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

如果是 11 月 29 日:

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

【问题讨论】:

  • 你能添加一个你想要数据的输出示例吗?
  • 您想按照与当前日期的接近程度对它们进行排序吗?如果是这样,那么2000-12-28 将最接近2021-11-29
  • 你好,我主要是想按月和日排序,年份对我来说并不重要
  • 如果在 11 月 29 日之前排序,根据您的输出,我无法理解您的排序。您是否尝试将 11 月 29 日之后的日期放在首位,然后放在最后一个日期之前?
  • 让我换一种说法。假设每个日期都是生日。我希望能够根据当前日期显示下一个生日。如果是 11 月 29 日,下一个生日是:11-3012-2805-3009-30

标签: javascript arrays sorting


【解决方案1】:

mm-dd转成mmdd再转成数字再使用Math.abs()如下如何?

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

所有日期未来

如果所有日期都被认为是现在或未来,我们可以采用以下概念:

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

【讨论】:

  • 您好,非常感谢您的帮助。然而,这并不是我想要的结果。结果应按以下顺序排列:11-30、12-28、05-3009-30
  • ...基于当前日期的下一个生日...所以您想将所有日期视为未来?这改变了一切;很快就会看看。
  • 就是这样,我知道这不是一件简单的事情;)
  • 查看第二个选项,该选项将大部分处理从排序功能中移除。
  • 就是这样!真的很完美!非常感谢!
【解决方案2】:

您可以使用Array.sort() 为您提供所需的结果,我已将输入数组中的日期移至今年:

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

【讨论】:

  • 非常感谢您的回答。然而,结果并不完全正确。实际上,id 应该按以下顺序排列:2、1、4、3(2021-11-30、2021-12-28、2021-05-30、2021-09-30)
  • 太棒了,我只是不确定为什么 2021-05-30 的排序顺序高于 2021-09-30。你能解释一下吗?谢谢!
  • 确实,我明白我的要求不太合乎逻辑。其实年份并不是真的需要,我主要是想按月和天排序。我已经修改了我的问题,希望它会更清楚一点。
猜你喜欢
  • 1970-01-01
  • 2019-06-18
  • 1970-01-01
  • 2021-02-23
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多