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

omjgkv6w  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(107)

我们试图针对List<T>编写一个LINQ语句,该语句从该列表的末尾向后搜索条件,但在指定的'T'项处停止。
例如,如果列表有1000个项目,而“limit”项目位于位置995(索引994),那么我们只想搜索最后六个项目以查找测试条件。我们需要尽可能高的性能。
然而,要使用LINQ,我们知道的唯一方法是获取“limit”项的现有索引,这是昂贵的,然后在整个源集合上运行一个Select with index,这也是昂贵的,就像这样...

// 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?

igetnqfo

igetnqfo1#

你不需要这些。

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

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

8yparm6h

8yparm6h2#

我正在查看.NET源代码,看起来.Reverse在内部调用了.ToArray,它迭代了整个集合。这会扼杀所有的性能优势。https://source.dot.net/#System.Linq/System/Linq/Reverse.cs,57
因此,如果您已经知道该项目位于“更接近末尾”的位置,请使用内部针对IList进行优化的.LastOrDefault(它接受IList.Count并从其向后移动)。

相关问题