我有一个RekenReeks类,它返回从2开始的数字,乘以2.所以{2,4,8,16,32,64}
现在我了解了TakeWhile和SkipWhile方法以及LINQ。
所以我创建了3个应该存储完全相同的变量,但我的Console.WriteLine
只打印selection1而不是2和3。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
RekenReeks reeks = new RekenReeks(2, n => n * 2);
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
foreach (int i in selection)
{
Console.WriteLine("selection1 {0}",i);
}
foreach (int i in selection2)
{
Console.WriteLine("selection2 {0}", i);
}
foreach (int i in selection3)
{
Console.WriteLine("selection3 {0}", i);
}
Console.ReadLine();
}
}
public class RekenReeks : IEnumerable<int>
{
Func<int, int> getNew;
int number;
public RekenReeks(int starton, Func<int, int> getNewThing)
{
getNew = getNewThing;
number = starton;
}
public IEnumerator<int> GetEnumerator()
{
yield return number;
for (; ; )
{
yield return getNew(number);
number = getNew(number);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
答案 0 :(得分:7)
你的序列是无限的(理论上)。你假设太多了。程序的功能不可能知道您的序列严格单调增加。
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
这永远不会停止。由于where
将始终提取下一个值,因此不知道它的条件是否满足,它总是 来检查下一个值。
var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);
这将取值,而它们介于11和999之间。当序列以2开头时,它将在第一个值上停止。
var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);
这将在11到999之间跳过值。由于第一个是2,它将跳过无,因此产生 all 。
答案 1 :(得分:3)
hasBeenSet = true;
setTimeout(function(){ hasBeenSet = false}, 60000);
和TakeWhile()
都从序列的最开始处开始,并在条件不符合时停止/跳过。
SkipWhile()
例如,如果你把
// I've redesigned your ReekenReeks
// [2, 4, 8, 16, 32, 64, ..., 2**30]
var reeks = Enumerable
.Range(1, 30)
.Select(index => 1 << index);
由于 var selection2 = reeks
.TakeWhile(n => n < 1000 && n > 10);
的第一项reeks
,条件2
不符合n < 1000 && n > 10
停止并返回空序列。正确的实施是
TakeWhile
如果您想从序列( var selection2 = reeks
.SkipWhile(n => n <= 10)
.TakeWhile(n => n < 1000);
)的中间中删除值,则必须使用selection3
:
Where
打印 infinine 序列时要小心, var selection3 = reeks
.Where(n => !(n > 1000 && n < 10)); // cut theses items off
是个不错的选择:
.Take()
答案 2 :(得分:1)
var selection = from i in reeks
where i > 10
&& i < 1000
select i;
没有理由永远这样做。当i
为1024时,它将无法获得,但如果2048
小于1000
,或4096
小于{{1},它仍会检查}},或1000
小于8192
等等(最终要么发生溢出异常,要么1000
回绕到n
,然后将其设置为{{1}它仍然是0
)。
0 * 2
尝试的第一个值是0
。这不符合谓词reeks.TakeWhile(n => n < 1000 && n > 10)
,因为2
不正确。因此停止了。
n < 1000 && n > 10
2 > 10
没有reeks.SkipWhile(n => n > 1000 && n < 10)
的值。因此,这与完全没有n
相同。
看起来你想要的是:
n > 1000 && n < 10
在找到满足条件的第一个数字之前跳过,然后将所有符合条件的数字跳到第一个不符合条件的数字。