如何按多个日期字段对对象数组进行排序?

How to sort an array of objects by multiple date fields?

我有以下数据结构:

var dates = [
  {
    id: '1',
    date1: '2022-03-21T18:59:36.641Z',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '2',
    date1: '2022-03-20T18:59:36.641Z',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '3',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '4',
    date2: '2022-03-15T18:59:36.641Z',
  }
];

var sorted = dates.sort(function(a,b) {
      return (a.date1 > b.date1) ? 1 : -1
   });

console.log({sorted});

请注意,date1 并不总是可用,但 date2 是必需的。我想先按 date1 排序,然后按 date2 排序。我创建了这个 fiddle 来测试,但仍然没有弄明白: https://jsfiddle.net/y9sgpob8/4/

请帮我弄清楚如何按以下顺序得到结果:

[{
  date1: "2022-03-20T18:59:36.641Z",
  date2: "2022-03-17T18:59:36.641Z",
  id: "2"
}, {
  date1: "2022-03-21T18:59:36.641Z",
  date2: "2022-03-17T18:59:36.641Z",
  id: "1"
}, {
  date2: "2022-03-15T18:59:36.641Z",
  id: "4"
}, {
  date2: "2022-03-17T18:59:36.641Z",
  id: "3"
}]

您需要根据

排序
  • 是否date1存在
  • 然后根据date1
  • 然后根据date2

由于日期是ISO格式,可以进行字符串比较排序

const input=[{id:"1",date1:"2022-03-21T18:59:36.641Z",date2:"2022-03-17T18:59:36.641Z",},{id:"2",date1:"2022-03-20T18:59:36.641Z",date2:"2022-03-17T18:59:36.641Z",},{id:"3",date2:"2022-03-17T18:59:36.641Z",},{id:"4",date2:"2022-03-15T18:59:36.641Z",}];

input.sort((a,b) => 
  ( ('date1' in b) - ('date1' in a) )
  || (a.date1 ?? '').localeCompare(b.date1 ?? '')
  || a.date2.localeCompare(b.date2)
)

console.log(input)

您也可以将只有 date2 的对象分开,然后排序,最后合并它。请参阅下面的代码段:

const dates = [
  {
    id: '1',
    date1: '2022-03-21T18:59:36.641Z',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '2',
    date1: '2022-03-20T18:59:36.641Z',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '3',
    date2: '2022-03-17T18:59:36.641Z',
  },
  {
    id: '4',
    date2: '2022-03-15T18:59:36.641Z',
  }
];

var array1 = [];
var array2 = [];

for (const date in dates) {
  if (dates[date].date1) {
    array1.push(dates[date]);
  } else {
   array2.push(dates[date]);
  }
}

var sorted1 = array1.sort(function(a,b) {
      return (a.date1 > b.date1) ? 1 : -1
   }); 
   
var sorted2 = array2.sort(function(a,b) {
      return (a.date2 > b.date2) ? 1 : -1
   }); 
   
const sorted = sorted1.concat(sorted2);  
console.log({sorted});

所有没有date1的记录都会在结果的末尾找到,对吧? 如果是这样,您可以分离成 2 个数组并合并它们。

const dates=[{id:"1",date1:"2022-03-21T18:59:36.641Z",date2:"2022-03-17T18:59:36.641Z",},{id:"2",date1:"2022-03-20T18:59:36.641Z",date2:"2022-03-17T18:59:36.641Z",},{id:"3",date2:"2022-03-17T18:59:36.641Z",},{id:"4",date2:"2022-03-15T18:59:36.641Z",}];

const timeStamp = value => new Date(value).valueOf()

const arrWithDate1 = dates
                      .filter(elem => elem.date1)
                      .sort((a, b) => (timeStamp(a.date1) - timeStamp(b.date1)))

const arrWithDate2 = dates
                      .filter(elem => !elem.date1)
                      .sort((a, b) => (timeStamp(a.date2) - timeStamp(b.date2)))

console.log([...arrWithDate1, ...arrWithDate2]);