列出列表中的每个第二个对象

时间:2010-08-25 16:16:22

标签: c# .net linq linq-to-objects

我有一个IEnumerable,我想获得一个包含每个第n个元素的新IEnumerable。

这可以在Linq完成吗?

3 个答案:

答案 0 :(得分:23)

我自己想出来了......

IEnumerable<T>.Where()方法有一个重载,它接受当前元素的索引 - 正是医生所要求的。

(new []{1,2,3,4,5}).Where((elem, idx) => idx % 2 == 0);

这将返回

{1, 3, 5}

更新:为了涵盖我的用例和Dan Tao的建议,我们还要指定第一个返回的元素应该是什么:

var firstIdx = 1;
var takeEvery = 2;
var list =  new []{1,2,3,4,5};

var newList = list
    .Skip(firstIdx)
    .Where((elem, idx) => idx % takeEvery == 0);

...将返回

{2, 4}

答案 1 :(得分:8)

实施Cristi's suggestion

public static IEnumerable<T> Sample<T>(this IEnumerable<T> source, int interval)
{
    // null check, out of range check go here

    return source.Where((value, index) => (index + 1) % interval == 0);
}

用法:

var upToTen = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var evens = upToTen.Sample(2);
var multiplesOfThree = upToTen.Sample(3);

答案 2 :(得分:0)

虽然不是LINQ,但您也可以使用yield创建扩展方法。

public static IEnumerable<T> EverySecondObject<T>(this IEnumerable<T> list)
{
    using (var enumerator = list.GetEnumerator())
    {
        while (true)
        {
            if (!enumerator.MoveNext())
                yield break;
            if (enumerator.MoveNext())
                yield return enumerator.Current;
            else
                yield break;
        }
    }
}