javascript - 自定义日期范围排序

标签 javascript sorting typescript

我正在尝试一个项目,尝试在 native 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"
  },

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

这就是当前使用 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 的工作方式与 native 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

关于javascript - 自定义日期范围排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43313875/

相关文章:

javascript - 使用 Laravel Collection 方法将值插入选择列表选项的方法。

javascript - 什么是良好的独立于浏览器的 JavaScript 编程环境?

c# - 为什么这些快速排序算法不能完全工作?

python - 如何在Python中将十六进制代码行(\x)获取到十六进制地址(0x)?

Angular2 等待 $http 响应

javascript - 使用 CryptoJS 在 Javascript 中进行 Java AES 加密

javascript - Ctrl+单击带有单击处理程序的链接

python - 在python中对字典键进行排序

javascript - 是否可以为 TypeScript 类实现析构函数?

javascript - ngx-gauge 不显示接收到的数据