Linq中是否有与ElementAt
相同的方法,除了它返回一个带有单个元素的IEnumerable<T>
,而不是实际的元素?是不是我可以使用一些SelectRange(startIndex, endIndex)
方法并且只传递两次相同的索引?
答案 0 :(得分:12)
最简单的方法是使用
source.Skip(count).Take(1)
或更一般地
source.Skip(startIndex).Take(endIndex - startIndex)
(假设包含startIndex
但仅限endIndex
)。
答案 1 :(得分:3)
啊..它被称为GetRange(index, count)
。我的错。刚发现它:)
答案 2 :(得分:3)
Jon Skeet的技巧是一种很好的方法。不过,我建议基于Enumerable.Skip
中的实施细节进行可能的优化:它目前似乎没有利用IList
或IList<T>
上的索引器。幸运的是,Enumerable.ElementAt
确实如此。
所以另一种解决方案是:
var itemAsSequence = new[] { source.ElementAt(index) };
请注意,这将急切执行。如果你想要延迟执行语义类似于Jon的答案,你可以做类似的事情:
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);
我应该指出,由于这依赖于实现细节,LINQ to Objects的未来改进可能会使这种优化变得多余。
答案 3 :(得分:1)
编写扩展方法
public static IEnumerable<T> ToMyEnumerable<T>(this T input)
{
var enumerbale = new[] { input };
return enumerbale;
}
source.First( p => p.ID == value).ToMyEnumerable<T>()
是O(n)