Linq Enumerable <t> .ElementAt =&gt;的IEnumerable <T> </T> </T>

时间:2010-11-09 06:20:11

标签: c# linq

Linq中是否有与ElementAt相同的方法,除了它返回一个带有单个元素的IEnumerable<T>,而不是实际的元素?是不是我可以使用一些SelectRange(startIndex, endIndex)方法并且只传递两次相同的索引?

4 个答案:

答案 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中的实施细节进行可能的优化:它目前似乎没有利用IListIList<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)