简体   繁体   English

如何按日期对对象数组进行排序,但首先是最新日期?

[英]How to sort array of objects by date but with most current date first?

I've got the array of objects:我有对象数组:

const data = [{
  "id": "1",
  "effectiveDate": "2023-01-21"
}, {
  "id": "2",
  "effectiveDate": "2023-02-22"
}, {
  "id": "3",
  "effectiveDate": "2022-05-04"
}, {
  "id": "4",
  "effectiveDate": "2022-05-05"
}, {
  "id": "5",
  "effectiveDate": "2021-01-21"
}, {
  "id": "6",
  "effectiveDate": "2021-02-22"
}];

What I'm after is the way to sort it in the way that the object with the most current date is on index 0 and the rest of the objects are ordered ascending from the oldest to future dates, like this:我所追求的是以具有最新日期的对象位于索引 0 上的方式对其进行排序的方式,其余对象从最旧的日期到未来的日期按升序排列,如下所示:

[{
  "id": "4",
  "effectiveDate": "2022-05-05"
}, {
  "id": "5",
  "effectiveDate": "2021-01-21"
}, {
  "id": "6",
  "effectiveDate": "2021-02-22"
}, {
  "id": "3",
  "effectiveDate": "2022-05-04"
}, {
  "id": "1",
  "effectiveDate": "2023-01-21"
}, {
  "id": "2",
  "effectiveDate": "2023-02-22"
}]

The way I'm sorting it is:我排序的方式是:

const orderedDates = data.sort((a, b) => {
  const dateCompareResult = new Date(a.effectiveDate) - new Date(b.effectiveDate);
  return dateCompareResult;
});

which obviously gives me dates sorted ascending from the past dates to the future dates with the most current date somewhere in between.这显然给了我从过去日期到未来日期升序排列的日期,最新日期介于两者之间。 How can I move the most current date object to index 0?如何将最新的日期对象移动到索引 0?

 function getItemsInAscendingDateOrderAndClosestToNowFirst(arr) { const time = Date.now(); const [closest, ...rest] = Array // create a shallow copy in order to // not mutate the original reference. .from(arr) // sort items by date closest to now. .sort((a, b) => { const aTime = new Date(a.effectiveDate).getTime(); const bTime = new Date(b.effectiveDate).getTime(); const aDelta = Math.abs(time - aTime); const bDelta = Math.abs(time - bTime); return (aDelta - bDelta); }); return [ closest, ...rest // sort all other items in ascending date order. .sort((a, b) => new Date(a.effectiveDate).getTime() - new Date(b.effectiveDate).getTime() ), ]; } const data = [{ "id": "1", "effectiveDate": "2023-01-21" }, { "id": "2", "effectiveDate": "2023-02-22" }, { "id": "3", "effectiveDate": "2022-05-04" }, { "id": "4", "effectiveDate": "2022-05-05" }, { "id": "5", "effectiveDate": "2021-01-21" }, { "id": "6", "effectiveDate": "2021-02-22" }]; const sortedData = getItemsInAscendingDateOrderAndClosestToNowFirst(data); console.log({ sortedData });
 .as-console-wrapper { min-height: 100%!important; top: 0; }

I think the simplest way is to sort from oldest to newest, then move the element that's closest to today to the start, eg我认为最简单的方法是从最旧到最新排序,然后将最接近今天的元素移到开头,例如

 let data = [{"id": "1","effectiveDate": "2023-01-21"}, {"id": "2","effectiveDate": "2023-02-22"}, {"id": "3","effectiveDate": "2022-05-04"}, {"id": "4","effectiveDate": "2022-05-05"}, {"id": "5","effectiveDate": "2021-01-21"}, {"id": "6","effectiveDate": "2021-02-22"}]; // Sort from oldest to youngest data.sort((a, b) => b.effectiveDate.localeCompare(a.effectiveDate)); // Get today as milliseconds let today = new Date().toLocaleDateString('en-CA'); let todayMS = Date.parse(today); // Get index of closest element to today let closestIndex = data.reduce((acc, obj, index) => { let diff = Math.abs(Date.parse(obj.effectiveDate) - todayMS); return acc.diff > diff? {diff, index} : acc; }, {diff: Infinity, index:null}).index; // Move closest element to start of array data.unshift(data.splice(closestIndex, 1)); console.log(data);

One of the benefits of ISO 8601 formatted timestamps is that lexical comparisons give correct results. ISO 8601 格式时间戳的好处之一是词法比较给出了正确的结果。 If you don't want to use string comparison then the comparison function can be:如果您不想使用字符串比较,那么比较函数可以是:

data.sort((a, b) => Date.parse(b) - Date.parse(a))

but only if the timestamps are in one of the 3 formats supported by ECMA-262 (and fortunately, YYYY-MM-DD is one such format).但前提是时间戳是 ECMA-262 支持的 3 种格式之一(幸运的是,YYYY-MM-DD 是其中一种格式)。 :-) :-)

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

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