我有一个IEnumerable,我想获得一个包含每个第n个元素的新IEnumerable。
这可以在Linq完成吗?
答案 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)
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;
}
}
}