使用 IComparer 获取 DateTime 大于的索引

Using IComparer to get index where DateTime is greater than

鉴于:

List<DateTime> descOrderedDates;

还有一个日期时间:

DateTime fromDate;

我可以轻松统计日期大于fromDate的项目数,如下所示:

var count = descOrderedDates.Count(c=> c > fromDate);

但是我正在努力将其实现为 BinarySearch:

var ix = descOrderedDates.BinarySearch(fromDate, new CompareDates());

private class CompareDates : IComparer<DateTime>
{
    public int Compare(DateTime compareDate, DateTime fromDate)
    {
        if (fromDate > compareDate) return 1;
        return 0;
    }
}

fromDate 小于列表中最小日期的测试用例中,这会不断返回 1。我正在努力思考 IComparer,谁能告诉我我做错了什么?

你的比较器 returns 1 在 fromDate > compareDate 的情况下,但它也应该 return -1 在相反的情况下,只有当它们相等时才为 0。您是否需要自定义比较器?我相信对于日期,默认比较会正常工作。

您应该 return Compare 中的负值、正值或 0,具体取决于参数是否大于、小于或等于彼此,正如 documentation 所说。 (因此,您完全不 return 负值的实现是不正确的。)

您可以通过显式写出三种情况并将日期与 <> 进行比较来做到这一点,但是 DateTime 具有 CompareTo 方法(因为它实现 IComparable),所以你可以直接使用它:

public int Compare(DateTime date1, DateTime date2)
    => date2.CompareTo(date1);

注意我们调用CompareTo时两个日期的顺序是相反的,实现我们实现的Comparer的降序

如果你想找到列表中日期小于 fromDate 的第一个索引,你还需要对 ix:

做一些检查
int firstIndexLessThanFromDate;
if (ix < 0) {
    // applying bitwise not gives you where the element should be inserted
    // i.e. the index of the next smallest element
    firstIndexLessThanFromDate = ~ix;
} else {
    firstIndexLessThanFromDate = ix + 1;
}