简体   繁体   中英

Is there a more efficient LINQ statement to reverse-search for a condition in a List<T>?

We're trying to write a LINQ statement against a List<T> that searches backwards from the end of that list for a condition, but which stops at a specified 'T' item.

For instance, if the list has 1000 items and the 'limit' item is at position 995 (index 994), then we only want to search the last six items for the test condition. We need this to be as high-performance as possible.

However, to use LINQ, the only way we know is to get the existing index of the 'limit' item, which is expensive, then run a Select with index over the entire source collection, which also is expensive, like this...

// 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) );

So is there an easier way to tell Linq 'Stop enumerating if you've checked this item', or will I have to manually do it myself in an index-based loop and not use LINQ at all?

You don't need any of that.

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

Thanks to deferred execution (and assuming sourceList implements IList<T> ), this will iterate part of the list exactly once.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM