C# 我可以用LINQ以更紧凑的方式编写这个for循环吗?
有没有办法用LINQ清理这种类型的循环?我真的认为这个方法应该是LINQ的一行。但是我不明白 我的方法如下所示:C# 我可以用LINQ以更紧凑的方式编写这个for循环吗?,c#,linq,C#,Linq,有没有办法用LINQ清理这种类型的循环?我真的认为这个方法应该是LINQ的一行。但是我不明白 我的方法如下所示: int[] MakeList(int stepWidth) { var ret = new List<int>(); for (var i=0;i<360;i+=stepWidth) { ret.Add(i); } return ret.ToArray(); } 但是这个Enumerable.Range(0
int[] MakeList(int stepWidth)
{
var ret = new List<int>();
for (var i=0;i<360;i+=stepWidth)
{
ret.Add(i);
}
return ret.ToArray();
}
但是这个Enumerable.Range(0360)在我看来有点太粗糙了:)选择
和的组合。TakeWhile
可能是一种方法,但它看起来与其他方法非常接近
var result = Enumerable.Range(0, int.MaxValue)
.Select(i => i * step)
.TakeWhile(i => i < 360)
.ToArray();
var result=Enumerable.Range(0,int.MaxValue)
.选择(i=>i*步)
.TakeWhile(i=>i<360)
.ToArray();
首先:您的代码既美观又可读
第二:不要害怕循环——循环完美地显示了程序员的意图。如果我必须更改某些内容,我会删除列表
:
int[]生成列表(int步长)
{
变量长度=(360+步长-1)/步长;
var ret=新整数[长度];
对于(变量i=0;i
第三:如果经常使用LINQ,我将返回IEnumerable
(请参阅生成器):
IEnumerable生成序列(int-step)
{
对于(变量i=0;i<360;i+=步长)
收益率i;
}
并按如下方式使用:MakeSequence(x).ToArray()
或MakeSequence(x)。[SomeLinqMethods]
答案是否定的,并不比你所拥有的高。此外,不要害怕可读的代码。我不认为你的解决方案是粗糙的。它可以做你想要的,你将永远需要步长方面。@TheGeneral:我想这取决于你喜欢什么。。我真的很喜欢LINQ,我认为LINQ表达式比我的MakeList方法读起来更快。你可以稍微加快一点Enumerable.Range(0,360/stepWidth)。Select(x=>x*stepWidth)。ToArray()
我认为它已经足够清晰了,但是如果你经常这样称呼它,它当然可以被优化,这样它就只创建一个数组,而不会创建一个列表,然后将该列表的内容复制到一个数组中……讽刺的是,如果你把Linq方法中所有的非空白字符加起来,它实际上比OP的代码长(而且更难阅读,IMO)。@MatthewWatson,我认为(IMO:),TakeWhile
更能描述意图,甚至更长,它只会重复所需的次数,其中where
将迭代范围内的所有数字。对于stepWidth
的某些值,这实际上不会返回正确的结果。例如,尝试使用stepWidth==7
并将其与OP的结果进行比较。它将少返回一个值。实际计数需要四舍五入,例如(360+stepWidth-1)/stepWidth
谢谢Matthiew,你说得对。更正。发电机已检查,正常工作。
var result = Enumerable.Range(0, int.MaxValue)
.Select(i => i * step)
.TakeWhile(i => i < 360)
.ToArray();
int[] MakeList(int stepWidth)
{
var length = (360 + stepWidth - 1) / stepWidth;
var ret = new int[length];
for (var i = 0; i < length; i++)
{
ret[i] = i * stepWidth;
}
return ret;
}
IEnumerable<int> MakeSequence(int step)
{
for (var i = 0; i < 360; i += step)
yield return i;
}