C# 将丑陋的循环重构为LINQ
我有下面的代码和平,它将C# 将丑陋的循环重构为LINQ,c#,linq,C#,Linq,我有下面的代码和平,它将int因子化为素数: private static IEnumerable<int> Factor(int input) { IList<int> result = new List<int>(); while (true) { var theSmallestDivisor = GetTheSmallestDivisor(input);
int
因子化为素数:
private static IEnumerable<int> Factor(int input)
{
IList<int> result = new List<int>();
while (true)
{
var theSmallestDivisor = GetTheSmallestDivisor(input);
if (theSmallestDivisor == 0)
{
result.Add(input);
return result;
}
result.Add(theSmallestDivisor);
input = input/theSmallestDivisor;
}
}
私有静态IEnumerable因子(int输入)
{
IList结果=新列表();
while(true)
{
var theSmallestDivisor=获取最小除数(输入);
如果(最小除数==0)
{
结果。添加(输入);
返回结果;
}
结果。添加(最小除数);
输入=输入/最小除数;
}
}
我正在寻找关于如何改进它的提示,可能是使用LINQ。public IEnumerable GetFactors(int-input)
public IEnumerable<int> GetFactors(int input)
{
int first = Primes()
.TakeWhile(x => x <= Math.Sqrt(input))
.FirstOrDefault(x => input % x == 0);
return first == 0
? new[] { input }
: new[] { first }.Concat(GetFactors(input / first));
}
{
int first=Primes()
.TakeWhile(x=>x输入%x==0);
返回第一个==0
?新[]{input}
:new[]{first}.Concat(GetFactors(input/first));
}
这里有一个迭代器版本:
private static IEnumerable<int> Factor(int input)
{
while (true)
{
var theSmallestDivisor = GetTheSmallestDivisor(input);
if (theSmallestDivisor == 0)
{
yield return input;
yield break;
}
yield return theSmallestDivisor;
input = input / theSmallestDivisor;
}
}
私有静态IEnumerable因子(int输入)
{
while(true)
{
var theSmallestDivisor=获取最小除数(输入);
如果(最小除数==0)
{
收益投入;
屈服断裂;
}
收益率返回最小除数;
输入=输入/最小除数;
}
}
LINQ只会使该代码在特定情况下的可读性降低。LINQ的运算符主要用于从现有列表生成新列表。e、 g
IEnumerable<B> LinqOperator(this IEnumerable<A> list, ...)
IEnumerable LINQ运算符(此IEnumerable列表,…)
与其说是从头开始生成一个列表,不如说是您正在尝试这样做
但是,既然您返回的是IEnumerable,那么不妨将其设置为懒惰:
private static IEnumerable<int> Factor(int input)
{
while (true)
{
var theSmallestDivisor = GetTheSmallestDivisor(input);
if (theSmallestDivisor == 0)
{
yield return input;
yield break;
}
yield return theSmallestDivisor;
input = input/theSmallestDivisor;
}
}
私有静态IEnumerable因子(int输入)
{
while(true)
{
var theSmallestDivisor=获取最小除数(输入);
如果(最小除数==0)
{
收益投入;
屈服断裂;
}
收益率返回最小除数;
输入=输入/最小除数;
}
}
您的循环有什么问题?我没看到林克在这里帮忙。您没有编写查询。新的闪亮锤子(LINQ)。。。一切看起来都像钉子:)好吧,LINQ不仅仅是关于查询,尽管它的名字。当前代码是14行,如果有一行LINQ替代方案,我会非常高兴。@john_mm同意,但它主要用于查询。甚至像Union
、Cast
和of type
这样的函数也是与查询相关的。我脑海中唯一没有想到的是ForEach
。话虽如此,您是对的(尽管我仍然认为LINQ在这里没有用处)。什么是获取最小除数()
?它是在哪里定义的?素数是从哪里来的?你真的认为它比给定的例子好吗?也许更聪明一些,但它实际上不是同一个算法,而且很难理解/阅读。非常感谢Darshana。我会用你的代码玩一玩。我已经有了一种方法来实现Primes
:Enumerable.Range(23000)。其中(I=>Enumerable.Range(2,Math.Max(0,I-2))。All(i1=>I%i1!=0))
。谢谢Lucas,这看起来很不错。我想知道是否有办法消除input=input/smallestdivisior
assignment,并有一个更像函数的程序,具有不可变的值。。。完美是好的敌人,这在我看来已经足够好了。如果你想要函数式风格,你就必须使用递归,它会更慢,更容易发生堆栈溢出,更难阅读,或者做一些复杂的事情来避免递归。哦,你可以使用input/=最小的除数代码>如果您愿意;)