将一个丑陋的循环重构到LINQ中
本文关键字:循环 重构 LINQ 一个 | 更新日期: 2023-09-27 18:14:36
我有以下和平的代码,将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;
}
}
我正在寻找如何改进它的提示,可能使用LINQ。
这是一个迭代器版本:
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;
}
}
LINQ只会在这种情况下降低代码的可读性。
LINQ的操作符主要用于从现有列表生成新列表。例如
IEnumerable<B> LinqOperator(this IEnumerable<A> list, ...)
不是为了从头开始生成列表,而是为了尝试这样做。
但是,由于您返回的是IEnumerable,您不妨将其设置为lazy:
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;
}
}
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));
}