You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用IComparer对降序DateTime列表二分查找大于指定值的索引问题

问题原因

你当前的实现存在两个核心错误:

  • IComparer的Compare方法返回值不符合规范
    Compare(x,y)的返回值必须严格遵循以下规则,BinarySearch才能正常工作:
    • 返回值 < 0:代表x小于y
    • 返回值 = 0:代表x等于y
    • 返回值 > 0:代表x大于y
      你现有的比较器仅返回1和0两种结果,完全不符合要求,导致BinarySearch无法计算出正确的索引位置。
  • 没有适配列表的降序排序规则
    .NET内置的List<T>.BinarySearch默认是为升序排列的列表设计的,你的列表是降序排列,比较器的逻辑需要和排序规则保持一致。

修复方案

第一步:实现符合要求的降序比较器

private class DescendingDateTimeComparer : IComparer<DateTime>
{
    public int Compare(DateTime x, DateTime y)
    {
        // 降序比较逻辑,和默认升序的CompareTo结果相反即可
        return y.CompareTo(x);
    }
}

第二步:正确处理BinarySearch的返回值

BinarySearch的返回值规则:找到匹配项则返回对应索引,未找到则返回负数,对负数做按位取反(~)得到的就是目标值应该插入的位置,这个位置正好等于所有大于fromDate的元素数量。
完整统计代码如下:

var comparer = new DescendingDateTimeComparer();
var searchResult = descOrderedDates.BinarySearch(fromDate, comparer);
int count;

if (searchResult >= 0)
{
    // 存在和fromDate相等的元素,需要定位到第一个相等元素的索引
    // 避免重复相等的日期影响统计结果
    while (searchResult > 0 && comparer.Compare(descOrderedDates[searchResult - 1], fromDate) == 0)
    {
        searchResult--;
    }
    count = searchResult;
}
else
{
    // 未找到匹配项,按位取反得到插入位置就是大于fromDate的元素个数
    count = ~searchResult;
}

你之前测试异常的原因

你错误的比较器返回值导致BinarySearch的索引计算完全错乱,当fromDate小于列表最小日期时,本应该返回对应列表长度的计数,却返回了错误的1。

内容的提问来源于stack exchange,提问作者Tom Gullen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:15:04