按字符串日期值排序数组未返回正确的结果顺序(降序)

时间:2019-02-11 04:40:38

标签: javascript arrays lodash

我正在尝试在字符串日期上对数组进行排序,但是遇到了一些问题。

我的数组称为:myArray,并具有以下示例信息:

0: {…}
​​
deployed_date: "29/01/2019 14:08:44"
​​last_restored_date: "11/01/2019 11:22:22"

1: {…}
​​
deployed_date: "29/01/2019 14:08:19"
​​
2: {…}
​​
​​deployed_date: "29/01/2019 11:34:23"
​​
3: {…}
​​
deployed_date: "11/02/2019 11:24:33"
​​
4: {…}
​​
deployed_date: "11/02/2019 11:24:24"
​​last_restored_date: "11/01/2019 11:25:42"

我同时使用了Lodash和本机JavaScript排序,但是不幸的是,我无法单独对这个deploy_date进行降序排序。

仅供参考,我也在使用momentjs:

myArray[key].deployed_date = moment(value.deployed_date,'YYYYMMDDHHmmss').format('DD/MM/YYYY HH:mm:ss');

我用过:

_.orderBy(myArray, ['deployed_date'],['desc']) // lodash

以及

myArray.sort()

订单显示在上面的数组中。

我不确定是否与数组索引1,2和3没有一个last_restored_date值有关,但是由于某种原因,该数组未按deploy_date desc正确排序。

>

我期望的结果是:

11/02/2019 11:24:33
11/02/2019 11:24:24
29/01/2019 14:08:44
29/01/2019 14:08:19
29/01/2019 11:34:23

如何达到此处显示的预期结果顺序?

5 个答案:

答案 0 :(得分:1)

请先使用矩库将日期格式设置为“ DD / MM / YYYY HH:mm:ss”,然后以下代码将排序并返回结果 x.sort((a,b)=>{ return moment(a,'DD/MM/YYY HH:mm:ss').isAfter(moment(b,'DD/MM/YYY HH:mm:ss')) ? -1 : 1 })

答案 1 :(得分:0)

您可以像这样在结果数组上使用map以获得预期结果

let new_arr = foo.map( (obj) => {  
   return obj.deployed_date;
 ); 

希望有道理

答案 2 :(得分:0)

一种解决方案是在使用String::localeCompare()比较两个对象的deployed_date时将日期映射为标准格式:

const myArray = [
  {deployed_date: "29/01/2019 14:08:44", last_restored_date: "11/01/2019 11:22:22"},
  {deployed_date: "29/01/2019 14:08:19"},
  {deployed_date: "29/01/2019 11:34:23"},
  {deployed_date: "11/02/2019 11:24:33"},
  {deployed_date: "11/02/2019 11:24:24", last_restored_date: "11/01/2019 11:25:42"}
];

myArray.sort((a, b) =>
{
    let [aDate, aHour] = a.deployed_date.split(" ");
    let [bDate, bHour] = b.deployed_date.split(" ");
    let [aDay, aMonth, aYear] = aDate.split("/");
    let [bDay, bMonth, bYear] = bDate.split("/");
    let newADate = `${aYear}/${aMonth}/${aDay} ${aHour}`;
    let newBDate = `${bYear}/${bMonth}/${bDay} ${bHour}`;
    
    return newBDate.localeCompare(newADate);
});

console.log(myArray);

答案 3 :(得分:0)

const toDate = str => {
  const [d, t] = str.split(' ')
  return new Date(`${d.split('/').reverse().join('-')}T${t}Z`).getTime();
};

const compareByDate = (x, y) => toDate(y.deployed_date) - toDate(x.deployed_date);

const arr = [
  {deployed_date: "29/01/2019 14:08:44"},
  {deployed_date: "29/01/2019 14:08:19"},
  {deployed_date: "29/01/2019 11:34:23"},
  {deployed_date: "11/02/2019 11:24:33"},
  {deployed_date: "11/02/2019 11:24:24"}
];

arr.sort(compareByDate);
console.log(arr);

说明

  1. 将每个日期转换为ISO字符串日期(标准格式)
  2. 从该字符串中提取一个数字(使用Date.getTime())以便于比较。使用Date构造函数将字符串更改为Date。然后将该日期转换为毫秒
  3. 由于您想要降序(反转),因此请确保在比较器函数中反转操作数。 (x, y) => y - x;
  4. 一旦您将数字作为日期,就可以基于键deployed_date使用Array.sort

注意

我们要使用的ISO格式为YYYY-MM-DDTHH:MM:SSZ。并且由于我们拥有29/01/2019 14:08:44,因此我们需要进行一些处理。

  1. ' '分割字符串以分隔时间日期
  2. 由于拆分返回2个项目的数组,因此可以使用array destructuring操作。
  3. '/'分隔日期,并反转数组,因为我们需要YYYY-MM_DD。然后使用join字符'-'
  4. 使用new Date(...)创建日期,然后使用Date.getMilliseconds()将日期转换为毫秒

答案 4 :(得分:0)

从我的角度来看,您对lodash的orderBy的使用很好,它应该已经按预期对数据进行了排序。造成您问题的原因是您正在对字符串而不是日期进行排序,并且字符串的格式为DD / MM / YYYY,如果要对其进行排序,则不理想:01/01/2019是«早于»2018/12/31 (虽然毫无意义)。

您可以做什么: 1 /您可以使用日期或矩数据代替字符串 2 /或将日期格式设置为YYYY-MM-DD ...等 3 /或将一个函数传递给排序函数ˋ_.orderBy(myArray,[d => moment(d.deployed_data,...)],['desc'])`