繁体   English   中英

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

[英]Sort array on string date value not returning the correct result order (descending)

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

我的数组称为: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

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

请先使用矩库将日期格式设置为'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 })

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

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

希望有道理

一种解决方案是使用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); 

 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. 一旦你有数字日期,你可以使用的Array.sort基于关键deployed_date

注意

我们要使用的ISO格式为YYYY-MM-DDTHH:MM:SSZ 而且由于我们有29/01/2019 14:08:44我们需要做一些处理。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM