在Javascrpt中按日期对数组进行排序

时间:2019-06-15 16:43:06

标签: javascript arrays

我正在使用 sort()按日期对数组进行排序

elements = data.sort(function(a, b) {
    return a.date.getTime() - b.date.getTime()
});

问题是某些元素缺少日期(或日期无效) 并导致此错误:

无法读取未定义

的属性“ getTime”

更新:我已经准备好使用

我应该在哪里检查日期是否为有效日期,然后使用它对数组进行排序?

更新:这是我的数据

[{
        "date": "2019-06-15 14:57:13",
        "user": "john"
    },
    {
        "date": "2019-06-15 05:48:01",
        "user": "mike"
    },
    {
        "date": "bad-date-format",
        "user": "donna"
    },
    {
        "date": "2019-06-08 10:45:09",
        "user": "Ismil"
    },
    {
        "date": "",
        "user": "Daniel17"
    }
]

这是我期望的输出

[
    {
        "date": "2019-06-15 14:57:13",
        "user": "john"
    },
    {
        "date": "2019-06-15 05:48:01",
        "user": "mike"
    },
    {
        "date": "2019-06-08 10:45:09",
        "user": "Ismil"
    },
    {
        "date": "bad-date-format",
        "user": "donna"
    },
    {
        "date": "",
        "user": "Daniel17"
    }
]

7 个答案:

答案 0 :(得分:3)

您可以检查该属性是否存在,是否具有所需的格式,然后按字符串降序对日期进行排序,如果格式无效,则取布尔值的差值。

function checkDate(string) {
    return typeof string === 'string'
        && /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(string);
}

var array = [{ date: "2019-06-15 14:57:13", user: "john" }, { date: "2019-06-15 05:48:01", user: "mike" }, { date: "bad-date-format", user: "donna" }, { date: "2019-06-08 10:45:09", user: "Ismil" }, { date: "", user: "Daniel17" }];

array.sort((a, b) => {
    var aC = checkDate(a.date),
        bC = checkDate(b.date);

    return aC && bC
        ? b.date.localeCompare(a.date)
        : bC - aC;
});

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

答案 1 :(得分:0)

根据OP的评论

  

按日期降序,没有损坏数据的应该放在数组的开头

let data = [{
  date: new Date('2019-01-03T00:00:00.000Z')
},{
  date: new Date('2020-01-03T00:00:00.000Z')
},{
  date: new Date('2018-01-03T00:00:00.000Z')
}, {}]


function safeGetTime(obj) {
  if (obj && obj.date && obj.date.getTime) {
    return obj.date.getTime();
  }
  return Number.MAX_SAFE_INTEGER; // replace with `return 0` to put invalid data at end of array
}

data.sort(function(a, b) {
  return safeGetTime(b) - safeGetTime(a)
});

console.log(data);

答案 2 :(得分:0)

您可以使用Date.parse来确保您有一个有效的日期,并在对两个参数都进行排序时对它们进行排序。否则,将有效日期排序为“较高”的那个排序:

let data = [{ "date": "2019-06-15 14:57:13", "user": "john" }, { "date": "2019-06-15 05:48:01", "user": "mike" }, { "date": "bad-date-format", "user": "donna" }, { "date": "2019-06-08 10:45:09", "user": "Ismil" }, { "date": "", "user": "Daniel17" } ]

let result = data.sort((a,b) => Date.parse(a.date) && Date.parse(b.date)
  ? new Date(b.date).getTime() - new Date(a.date).getTime()
  : Date.parse(a.date) ? -1 : 0
)

console.log(result)

答案 3 :(得分:0)

您不必检查字符串是否为有效日期。

这是一个有效的代码:

const data = [{
        "date": "2019-06-15 14:57:13",
        "user": "john"
    },
    {
        "date": "2019-06-15 05:48:01",
        "user": "mike"
    },
    {
        "date": "bad-date-format",
        "user": "donna"
    },
    {
        "date": "2019-06-08 10:45:09",
        "user": "Ismil"
    },
    {
        "date": "",
        "user": "Daniel17"
    }
];

const elements = data.sort((a, b) => (new Date(b.date).getTime() || -Infinity) - (new Date(a.date).getTime() || -Infinity));
console.log(elements);

上面代码背后的技巧是,new Date()将给您传递一个Invalid Date对象,如果您向该对象传递了一个无效的日期字符串,则在您执行其{{1 }}方法。

现在,因为您希望所有NaN都在底部,所以排序函数应该将这些getTime()视为数组中评分最低的,这就是Invalid Date的含义(最低的数字。如果添加任何数字,将导致Invalid Date)。

我认为-Infinite的排序方式在数组底部无关紧要。

答案 4 :(得分:-2)

data.sort(function(a, b) {
    if (typeof a.date !== 'undefined' && typeof b.date !== 'undefined') {
      return a.date.getTime() - b.date.getTime()
    }
    return 0
});

简单的示例

data = [{date:"100"},{date:null},{date:"1"}, {nodate:"10"}];

data.sort(function(a, b) {
    if (typeof a.date !== 'undefined' && typeof b.date !== 'undefined') {
      return a.date - b.date
    }
    return 0
});

console.log(data)

答案 5 :(得分:-2)

您可以使用&&运算符。

data.sort(function(a, b) {
    return (a.date && b.date && a.date.getTime && b.date.getTime && a.date.getTime() - b.date.getTime()) || 0
});

我希望使用辅助功能。

const validDate = (...arr) => arr.every(x => x.date && x.date.getTime);
data.sort(function(a, b) {
    return (validDate(a,b) && a.date.getTime() - b.date.getTime()) || 0
});

答案 6 :(得分:-2)

您可以在使用getTime

之前进行检查

let data = [{
  date: new Date('2019-01-03T00:00:00.000Z')
},{
  date: new Date('2020-01-03T00:00:00.000Z')
},{
  date: new Date('2018-01-03T00:00:00.000Z')
}, {}]

data.sort((a, b)=>{
  if(!isNaN(new Date(a.date).getTime()) && !isNaN(new Date(b.date).getTime())){
  return a.date.getTime() - b.date.getTime()
  } 
  return Infinity
});

console.log(data);