2010-11-09 46 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未來改進的對象能做出這樣的優化冗餘。

相關問題