我要创建一个扩展方法jump<T>
,它采用任意序列s,返回一个无限序列,其元素以循环方式访问并跳过n个元素。所以,如果step == 0,则返回所有序列(无限次),如果step == 1,让我们以区间[0-10]中的所有数字为例,将返回0,2,4, 6,8,10,1,3,5 ecc。如果步骤== 2,那么结果将是0,3,6,9,1,4,7,10。
显然这只是一个有序的int列表的例子,我需要用一个通用的T元素序列来做。
我如何实现这一目标?
为了测试它,我创建了一个nunit测试,如下所示:
[Test]
public void Jumping_validArg_IsOk()
{
var start = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
.Jumping(3)
.ToList()//remove this to make it work
.Take(4);
var expected = new[] {1, 5, 9, 2};
CollectionAssert.AreEquivalent(start, expected);
}
但似乎永远不会结束,它会抛出System.OutOfMemoryException
。
解决方案: 我修改了一点我选择的最佳答案,以这种方式使它更通用:
public static IEnumerable<T> Jump<T>(this IEnumerable<T> sequence, int step)
{
var pos = 0;
var list = sequence.ToList();
while (true)
{
yield return list[pos];
pos = (pos + step + 1) % list.Count;
}
}
这样它应该适用于所有IEnumerable。我在测试中添加了评论,以显示要删除的内容以使其正常工作。我希望这一切都是正确的。
答案 0 :(得分:2)
您可以使用yield return
语句轻松实现此目的:
public static IEnumerable<T> Jump<T>(this IList<T> data, int step) {
int pos = 0;
while(true) {
yield return data[pos];
pos = (pos + step) % data.Count;
}
}