Linq Enumerable<T>.ElementAt => IEnumerable<T>
Is there a method in Linq that does the same as ElementAt
except it returns an IEnumerable<T>
with a single element, rather than the actual element? Isn't there some SelectRange(startIndex, endIndex)
method I cou开发者_如何学Pythonld use and just pass the same index twice?
The simplest way would be to use
source.Skip(count).Take(1)
or more generally
source.Skip(startIndex).Take(endIndex - startIndex)
(assuming an inclusive startIndex
but exclusive endIndex
).
Ah.. it's called GetRange(index, count)
. My bad. Just found it :)
Jon Skeet's technique is a great way to do it. I would however suggest a possible optimization that is based on an implementation detail in Enumerable.Skip
: it does not currently appear to take advantage of indexers on IList
or IList<T>
. Fortunately, Enumerable.ElementAt
does.
So an alternate solution would be:
var itemAsSequence = new[] { source.ElementAt(index) };
Do note that this will execute eagerly. If you want deferred execution semantics similar to Jon's answer, you could do something like:
public static IEnumerable<T> ElementAtAsSequence<T>
(this IEnumerable<T> source, int index)
{
// if you need argument validation, you need another level of indirection
yield return source.ElementAt(index);
}
...
var itemAsSequence = source.ElementAtAsSequence(index);
I should point out that since this relies on an implementation detail, future improvements in LINQ to Objects could make this optimization redundant.
write an extension method
public static IEnumerable<T> ToMyEnumerable<T>(this T input)
{
var enumerbale = new[] { input };
return enumerbale;
}
source.First( p => p.ID == value).ToMyEnumerable<T>()
which is O(n)
精彩评论