当前位置:  开发笔记 > 编程语言 > 正文

LINQ Skip仍然枚举跳过的项目

如何解决《LINQSkip仍然枚举跳过的项目》经验,为你挑选了2个好方法。

在以下测试中:

int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Func boom = x => { Console.WriteLine(x); return x; };
var res = data.Select(boom).Skip(3).Take(4).ToList();
Console.WriteLine();
res.Select(boom).ToList();

结果是:

1
2
3
4
5
6
7

4
5
6
7

从本质上讲,我观察到在这个例子中,Skip()并且Take()工作得很好,Skip()并不像Take()那样懒惰.似乎Skip()仍然枚举跳过的项目,即使它没有返回它们.

如果我先做,这同样适用Take().我最好的猜测是,它需要至少枚举第一个跳过或跳过,以便查看下一个跳转到哪里.

为什么这样做?



1> Cory Nelson..:

Skip()Take()这两种操作上IEnumerable<>.

IEnumerable<>不支持向前跳过 - 它一次只能给你一件物品.考虑到这一点,您可以将Skip()更多内容视为过滤器 - 它仍会触及源序列中的所有项目,但它会过滤掉您告诉它的许多项目.而且重要的是,它会将它们从过去的任何东西中过滤掉,而不是用于它前面的任何东西.

所以,通过这样做:

data.Select(boom).Skip(3)

boom()在进入过滤器之前对每个项目执行操作Skip().

如果您改为将其更改为此,则会在之前进行过滤Select,您只会调用boom()其余项目:

data.Skip(3).Take(4).Select(boom)



2> Yeldar Kurma..:

如果您反编译Enumerable,您将看到以下实现Skip:

while (count > 0 && e.MoveNext())
  --count;

以及以下实施Take:

foreach (TSource source1 in source)
{
  yield return source1;
  if (--count == 0) break;
}

因此,这两种LINQ方法实际上都是通过这些项进行枚举的.不同之处在于枚举项是否将放置在生成的集合中.那是怎么回事IEnumerable.

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有