首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当集合被排序时,LINQ可以使用二进制搜索吗?

当集合被排序时,LINQ可以使用二进制搜索吗?
EN

Stack Overflow用户
提问于 2009-11-20 04:35:26
回答 3查看 15.3K关注 0票数 22

当我试图搜索的集合是有序的时,我能以某种方式“指示”LINQ使用二进制搜索吗?我正在使用一个填充了有序数据的ObservableCollection<T>,并且我正在尝试使用Enumerable.First()。在我的谓词中,我根据我的集合所依据的字段的值进行过滤。

EN

回答 3

Stack Overflow用户

发布于 2014-04-16 02:55:36

公认的答案是非常好的。

但是,我需要像List<T>.BinarySearch()一样,让BinarySearch返回较大的第一个项目的索引。

因此,我使用ILSpy查看了它的实现,然后将其修改为具有选择器参数。我希望它能像对我一样对别人有用:

代码语言:javascript
复制
public static class ListExtensions
{
    public static int BinarySearch<T, U>(this IList<T> tf, U target, Func<T, U> selector)
    {
        var lo = 0;
        var hi = (int)tf.Count - 1;
        var comp = Comparer<U>.Default;

        while (lo <= hi)
        {
            var median = lo + (hi - lo >> 1);
            var num = comp.Compare(selector(tf[median]), target);
            if (num == 0)
                return median;
            if (num < 0)
                lo = median + 1;
            else
                hi = median - 1;
        }

        return ~lo;
    }
}
票数 7
EN

Stack Overflow用户

发布于 2009-11-20 04:42:09

Enumerable.First(predicate)在只支持枚举的IEnumarable<T>上工作,因此它不能随机访问其中的项。

此外,您的谓词包含最终导致true或false的任意代码,因此无法指示测试项目是太低还是太高。为了执行二进制搜索,将需要此信息。

Enumerable.First(predicate)只能在遍历枚举时按顺序测试每一项。

票数 1
EN

Stack Overflow用户

发布于 2009-11-20 05:39:01

记住,所有的(?至少大多数) LINQ使用的扩展方法都是在IQueryable<T>IEnumerable<T>IOrderedEnumerable<T>IOrderedQueryable<T>上实现的。

这些接口都不支持随机访问,因此它们都不能用于二进制搜索。像LINQ这样的东西的好处之一是,您可以处理大型数据集,而不必从数据库返回整个数据集。显然,如果你甚至还没有所有的数据,你就不能二进制搜索一些东西。

但正如其他人所说,没有理由不能为IList<T>或其他支持随机访问的集合类型编写此扩展方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1766328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档