当我试图搜索的集合是有序的时,我能以某种方式“指示”LINQ使用二进制搜索吗?我正在使用一个填充了有序数据的ObservableCollection<T>
,并且我正在尝试使用Enumerable.First()。在我的谓词中,我根据我的集合所依据的字段的值进行过滤。
发布于 2014-04-16 02:55:36
公认的答案是非常好的。
但是,我需要像List<T>.BinarySearch()
一样,让BinarySearch返回较大的第一个项目的索引。
因此,我使用ILSpy查看了它的实现,然后将其修改为具有选择器参数。我希望它能像对我一样对别人有用:
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;
}
}
发布于 2009-11-20 04:42:09
Enumerable.First(predicate)
在只支持枚举的IEnumarable<T>
上工作,因此它不能随机访问其中的项。
此外,您的谓词包含最终导致true或false的任意代码,因此无法指示测试项目是太低还是太高。为了执行二进制搜索,将需要此信息。
Enumerable.First(predicate)
只能在遍历枚举时按顺序测试每一项。
发布于 2009-11-20 05:39:01
记住,所有的(?至少大多数) LINQ使用的扩展方法都是在IQueryable<T>
或IEnumerable<T>
或IOrderedEnumerable<T>
或IOrderedQueryable<T>
上实现的。
这些接口都不支持随机访问,因此它们都不能用于二进制搜索。像LINQ这样的东西的好处之一是,您可以处理大型数据集,而不必从数据库返回整个数据集。显然,如果你甚至还没有所有的数据,你就不能二进制搜索一些东西。
但正如其他人所说,没有理由不能为IList<T>
或其他支持随机访问的集合类型编写此扩展方法。
https://stackoverflow.com/questions/1766328
复制相似问题