是否有更有效的 LINQ 语句来反向搜索 List 中的条件

本文关键字:List 搜索 条件 有效 LINQ 语句 是否 | 更新日期: 2023-09-27 18:33:58

我们尝试针对从该列表末尾向后搜索条件但停止在指定的"T"项处的List<T>编写 LINQ 语句。

例如,如果列表有 1000 个项目,而"limit"项目位于位置 995(索引 994),那么我们只想搜索最后六个项目以查找测试条件。我们需要它尽可能高性能。

但是,要使用 LINQ,我们知道的唯一方法是获取"limit"项的现有索引,这很昂贵,然后对整个源集合运行带有索引的 Select ,这也是昂贵的,就像这样......

// Assume limitItem is of type Foo and sourceList is of type List<Foo> 
var limitIndex = sourceList.IndexOf(limitItem);
var sourceListWithIndex = sourceList.Select( (Foo, Index) => new { Foo, Index } );
var fooWithIndex = sourceListWithIndex
    .LastOrDefault(item =>
        (item.Foo.SomTestValue == true)
        &&
        (item.Index >= limitIndex) );

那么,有没有更简单的方法告诉 Linq"如果您已检查此项目,请停止枚举",还是我必须在基于索引的循环中自己手动执行此操作并且根本不使用 LINQ?

是否有更有效的 LINQ 语句来反向搜索 List<T> 中的条件

你不需要这些。

sourceList.Reverse()
          .TakeWhile(o => o != limitItem)
          .FirstOrDefault(o => ...);

由于延迟执行(并假设sourceList实现IList<T>),这将只迭代列表的一部分一次。

我正在查看 .NET 源代码,看起来像.Reverse内部.ToArray调用,这会迭代整个集合。这会扼杀所有性能优势。https://source.dot.net/#System.Linq/System/Linq/Reverse.cs,57

因此,如果您已经知道该项目在"接近终点"的地方 - 请使用针对内部IList优化的.LastOrDefault(它采用IList.Count并从中向后移动。