自定义日期范围排序

Custom date range sorting

我正在进行一个项目,试图在本机 JS 完成工作的地方删除不必要的第 3 方依赖项。我们使用 Underscore 的 _.sortBy 对日期数组进行排序,但出于某种原因,我还不能完全复制确切的排序顺序。

返回的数据未排序,如下所示:

{
    "title": "February 2016",
    "startTime": "2016-02-01T10:00:00.000Z",
    "endTime": "2016-03-01T09:59:59.000Z"
  },
  {
    "title": "Week of February 28 2016",
    "startTime": "2016-02-28T05:00:00.000Z",
    "endTime": "2016-03-06T04:59:59.000Z"
  },
  {
    "title": "March 2016",
    "startTime": "2016-03-01T10:00:00.000Z",
    "endTime": "2016-04-01T07:59:59.000Z"
  },
  {
    "title": "Week of March 06 2016",
    "startTime": "2016-03-06T05:00:00.000Z",
    "endTime": "2016-03-13T04:59:59.000Z"
  },
  {
    "title": "Week of March 13 2016",
    "startTime": "2016-03-13T05:00:00.000Z",
    "endTime": "2016-03-20T03:59:59.000Z"
  },

基本上它只需要标准日期排序,除了 "week of..." 范围应该出现在 之前 整个月份范围。

这是当前使用 Underscore 和 MomentJS(也使用 Typescript)完成的方式,它正确地按照我们想要的方式对其进行排序:

_.sortBy(dateRanges, (range: IDateRange) => {
  if (moment(range.endTime).diff(range.startTime, "days") > 7) {
    return range.endTime;
  } else {
    return range.startTime;
  }
});

我试图复制那个确切的输出,但没有使用 Underscore 或 MomentJS。这是我目前拥有的:

dateRanges.sort((r1: IDateRange, r2: IDateRange) => {
  //604800000 milliseconds in 1 week
  //easier to hard code number this than do all the math on each iteration here
  const isWholeMonth = r1.endTime.getTime() - r1.startTime.getTime() > 604800000;

  if (isWholeMonth) {
    if (r1.endTime > r2.endTime) {
      return 1;
    } else if (r1.endTime < r2.endTime) {
      return -1;
    }
    return 0;
  } else {
    //Make the week listings for a month appear before the entire month listings
    if (r1.startTime > r2.startTime) {
      return 1;
    } else if (r1.startTime < r2.startTime) {
      return -1;
    }
    return 0;
  }
});

它还没有完全正确排序,但我不太明白为什么。这是一个工作演示,可将这两个输出到控制台,因此
http://codepen.io/chrismbarr/pen/KWOaaE

Underscore 的 _sortBy 与原生 sort 的工作方式不同。您需要检查和比较不同的东西,具体取决于标题中是否有 'week'(或检查 startTime 和 endTime,由您决定):

interface IDateRange {
    title: string;
    startTime: Date;
    endTime: Date;
}

const dateRanges: IDateRange[] = [
  {
    "title": "February 2016",
    "startTime": "2016-02-01T10:00:00.000Z",
    "endTime": "2016-03-01T09:59:59.000Z"
  },
  {
    "title": "Week of February 28 2016",
    "startTime": "2016-02-28T05:00:00.000Z",
    "endTime": "2016-03-06T04:59:59.000Z"
  },
  {
    "title": "March 2016",
    "startTime": "2016-03-01T10:00:00.000Z",
    "endTime": "2016-04-01T07:59:59.000Z"
  },
  {
    "title": "Week of March 06 2016",
    "startTime": "2016-03-06T05:00:00.000Z",
    "endTime": "2016-03-13T04:59:59.000Z"
  },
  {
    "title": "Week of March 13 2016",
    "startTime": "2016-03-13T05:00:00.000Z",
    "endTime": "2016-03-20T03:59:59.000Z"
  },
  {
    "title": "October 2016",
    "startTime": "2016-10-01T08:00:00.000Z",
    "endTime": "2016-11-01T07:59:59.000Z"
  },
  {
    "title": "Week of October 02 2016",
    "startTime": "2016-10-02T04:00:00.000Z",
    "endTime": "2016-10-09T03:59:59.000Z"
  },
  {
    "title": "Week of October 30 2016",
    "startTime": "2016-10-30T04:00:00.000Z",
    "endTime": "2016-11-06T03:59:59.000Z"
  },
  {
    "title": "November 2016",
    "startTime": "2016-11-01T08:00:00.000Z",
    "endTime": "2016-12-01T09:59:59.000Z"
  },
  {
    "title": "Week of November 13 2016",
    "startTime": "2016-11-13T05:00:00.000Z",
    "endTime": "2016-11-20T04:59:59.000Z"
  },
  {
    "title": "Week of November 20 2016",
    "startTime": "2016-11-20T05:00:00.000Z",
    "endTime": "2016-11-27T04:59:59.000Z"
  },
  {
    "title": "Week of November 27 2016",
    "startTime": "2016-11-27T05:00:00.000Z",
    "endTime": "2016-12-04T04:59:59.000Z"
  },
  {
    "title": "December 2016",
    "startTime": "2016-12-01T10:00:00.000Z",
    "endTime": "2017-01-01T09:59:59.000Z"
  },
  {
    "title": "Week of December 04 2016",
    "startTime": "2016-12-04T05:00:00.000Z",
    "endTime": "2016-12-11T04:59:59.000Z"
  },
  {
    "title": "Week of December 11 2016",
    "startTime": "2016-12-11T05:00:00.000Z",
    "endTime": "2016-12-18T04:59:59.000Z"
  },
  {
    "title": "Week of December 25 2016",
    "startTime": "2016-12-25T05:00:00.000Z",
    "endTime": "2017-01-01T04:59:59.000Z"
  },
  {
    "title": "January 2017",
    "startTime": "2017-01-01T10:00:00.000Z",
    "endTime": "2017-02-01T09:59:59.000Z"
  },
  {
    "title": "Week of January 15 2017",
    "startTime": "2017-01-15T05:00:00.000Z",
    "endTime": "2017-01-22T04:59:59.000Z"
  },
  {
    "title": "Week of January 29 2017",
    "startTime": "2017-01-29T05:00:00.000Z",
    "endTime": "2017-02-05T04:59:59.000Z"
  },
  {
    "title": "February 2017",
    "startTime": "2017-02-01T10:00:00.000Z",
    "endTime": "2017-03-01T09:59:59.000Z"
  },
  {
    "title": "Week of February 05 2017",
    "startTime": "2017-02-05T05:00:00.000Z",
    "endTime": "2017-02-12T04:59:59.000Z"
  },
  {
    "title": "Week of February 12 2017",
    "startTime": "2017-02-12T05:00:00.000Z",
    "endTime": "2017-02-19T04:59:59.000Z"
  },
  {
    "title": "March 2017",
    "startTime": "2017-03-01T10:00:00.000Z",
    "endTime": "2017-04-01T07:59:59.000Z"
  },
  {
    "title": "Week of March 05 2017",
    "startTime": "2017-03-05T05:00:00.000Z",
    "endTime": "2017-03-12T04:59:59.000Z"
  },
  {
    "title": "Week of March 12 2017",
    "startTime": "2017-03-12T05:00:00.000Z",
    "endTime": "2017-03-19T03:59:59.000Z"
  },
  {
    "title": "Week of March 19 2017",
    "startTime": "2017-03-19T04:00:00.000Z",
    "endTime": "2017-03-26T03:59:59.000Z"
  },
  {
    "title": "Week of March 26 2017",
    "startTime": "2017-03-26T04:00:00.000Z",
    "endTime": "2017-04-02T03:59:59.000Z"
  }
];

////==============================

console.clear();

//Convert to real data objects...
for (const range of dateRanges) {
  range.startTime = moment(range.startTime).utc().toDate();
  range.endTime = moment(range.endTime).utc().toDate();
}


//OLD
const librarySort = _.sortBy(dateRanges, (range: IDateRange) => {
  if (moment(range.endTime).diff(range.startTime, "days") > 7) {
    return range.endTime;
  } else {
    return range.startTime;
  }
});

//NEW - changes made here
const nativeSort = dateRanges.sort((r1: IDateRange, r2: IDateRange) => {
  let firstPartToCompare;
  let secondPartToCompare;

  if(r1.title.indexOf('eek') > -1) {
    firstPartToCompare = r1.startTime;
  } else {
    firstPartToCompare = r1.endTime;
  }

  if(r2.title.indexOf('eek') > -1) {
    secondPartToCompare = r2.startTime;
  } else {
    secondPartToCompare = r2.endTime;
  }

  if (firstPartToCompare > secondPartToCompare) {
    return 1;
  } else if (firstPartToCompare < secondPartToCompare) {
    return -1;
  }
  return 0;
});

console.info("CORRECT order - old way")
console.table(librarySort);

console.info("ATTEMPT to duplicate - new way")
console.table(nativeSort);

http://codepen.io/anon/pen/GWVrwB