【发布时间】:2010-11-09 18:58:16
【问题描述】:
Linq 中是否有与ElementAt 相同的方法,只是它返回一个带有单个元素而不是实际元素的IEnumerable<T>?是不是有一些SelectRange(startIndex, endIndex) 方法我可以使用并且只传递相同的索引两次?
【问题讨论】:
Linq 中是否有与ElementAt 相同的方法,只是它返回一个带有单个元素而不是实际元素的IEnumerable<T>?是不是有一些SelectRange(startIndex, endIndex) 方法我可以使用并且只传递相同的索引两次?
【问题讨论】:
最简单的方法是使用
source.Skip(count).Take(1)
或更一般地
source.Skip(startIndex).Take(endIndex - startIndex)
(假设包含startIndex 但不包含endIndex)。
【讨论】:
source是List,那么Skip(count)会是O(1)吗?
啊.. 它叫GetRange(index, count)。我的错。刚刚找到了:)
【讨论】:
List 而不是 IEnumerable<T> 的一部分,它的工作方式会大不相同(因为它很急切)。
List<T>。乔恩的回答适用于任何IEnumerable。
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 的改进可能会使这种优化变得多余。
【讨论】:
写一个扩展方法
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)
【讨论】: