Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LINQ, how do I choose items at particular indexes?

If I have an IEnumerable<Foo> allFoos and an IEnumerable<Int32> bestFooIndexes, how can I get a new IEnumerable<Foo> bestFoos containing the Foo entries from allFoos at the indexes specified by bestFooIndexes?

like image 922
Johann Gerell Avatar asked Nov 27 '22 18:11

Johann Gerell


2 Answers

var bestFoos = bestFooIndexes.Select(index => allFoos.ElementAt(index));

If you're worried about performance and the collections are large engouh:

List<Foo> allFoosList = allFoos.ToList();
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
like image 188
Elisha Avatar answered Dec 16 '22 00:12

Elisha


Elisha's answer will certainly work, but it may be very inefficient... it depends on what allFoos is implemented by. If it's an implementation of IList<T>, ElementAt will be efficient - but if it's actually the result of (say) a LINQ to Objects query, then the query will be re-run for every index. So it may be more efficient to write:

var allFoosList = allFoos.ToList();
// Given that we *know* allFoosList is a list, we can just use the indexer
// rather than getting ElementAt to perform the optimization on each iteration
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);

You could to this only when required, of course:

IList<Foo> allFoosList = allFoos as IList<Foo> ?? allFoos.ToList();
var bestFoos = bestFooIndexes.Select(index => allFoosList[index]);
like image 24
Jon Skeet Avatar answered Dec 15 '22 22:12

Jon Skeet