将一个丑陋的循环重构为LINQ

时间:2014-07-24 22:48:13

标签: c# linq

我有以下代码安静,将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。

3 个答案:

答案 0 :(得分:5)

这是一个迭代器版本:

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只会使该代码在特定情况下的可读性降低。

答案 1 :(得分:3)

LINQ的运营商主要用于从现有列表生成新列表。 e.g。

IEnumerable<B> LinqOperator(this IEnumerable<A> list, ...)

与您尝试从头开始生成列表并非如此。

但是,既然你要返回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;
    }
}

答案 2 :(得分:-1)

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));
}