2010-11-09 47 views
1

是否有LINQ的,做同样的作为ElementAt除了它返回一个带有IEnumerable<T>单个元件,而不是实际的元件的方法?是不是有一些我可以使用的SelectRange(startIndex, endIndex)方法,只需传递两次相同的索引?LINQ的可枚举<T> .ElementAt =>的IEnumerable <T>

回答

12

最简单的方法是使用

source.Skip(count).Take(1) 

或更一般

source.Skip(startIndex).Take(endIndex - startIndex) 

(假定一个包容startIndex但独家endIndex)。

+0

如果'source'是一个'List','Skip(count)'是'O(1)'? – mpen 2010-11-09 06:32:11

+2

@Mark:不幸的是,我不相信Skip会为此优化,不会。一个洞的位,真的:( – 2010-11-09 07:13:14

3

啊..它叫做GetRange(index, count)。我的错。只是觉得:)

+0

不,这是'List'的一部分,而不是'IEnumerable ',它的工作方式会有所不同(因为它是渴望的)。 – 2010-11-09 06:22:59

+0

@Mark。仅适用于'List '。Jon的答案对于任何IEnumerable都可以工作 – jordanbtucker 2010-11-09 06:23:29

+0

@Jon。打我吧 – jordanbtucker 2010-11-09 06:23:50

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)

3

乔恩斯基特的技术是做一个伟大的方式。但是,我会建议可能的优化,该优化基于Enumerable.Skip中的实现细节:它目前似乎不利用IListIList<T>上的索引器。幸运的是,Enumerable.ElementAt呢。

所以一个替代的解决方案是:

var itemAsSequence = new[] { source.ElementAt(index) }; 

请注意,这会急切地执行。如果你想类似乔恩的答案延迟执行语义,你可以这样做:

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未来改进的对象能做出这样的优化冗余。

相关问题