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

Cri*_*scu 7 .net c# linq linq-to-objects

我有一个IEnumerable,我希望得到一个包含每个第n个元素的新IEnumerable.

这可以在Linq完成吗?

Cri*_*scu 23

我自己搞清楚了......

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

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

这会回来

{1, 3, 5}
Run Code Online (Sandbox Code Playgroud)

更新:为了涵盖我的用例和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);
Run Code Online (Sandbox Code Playgroud)

......会回来

{2, 4}
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用`idx + 1`来匹配"每个第N个元素"的描述; 至少对我来说,这表明返回的第一个元素应该是第N个元素.所以`{1,2,3,4,5}`中的每一个第二个元素 - 都是*me* - 表示`{2,4}`(你的代码返回`{1,3,5}`).不过,这可能是主观的. (5认同)
  • 我第一次在集合谓词中看到了对索引的一个非常可靠的用法,bravo,我不会想到这一点. (2认同)

Dan*_*Tao 8

实施Cristi的建议:

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);
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

var evens = upToTen.Sample(2);
var multiplesOfThree = upToTen.Sample(3);
Run Code Online (Sandbox Code Playgroud)

  • @Anthony:这只是一个例子,旨在立即理解.我知道有些开发人员必须查找`Enumerable.Range`. (2认同)