我正在尝试找到一种方法来从同一行中的Linq方法访问以前的值。
我希望能够在Linq中使用这种一般形式:
var values = Enumerable.Range( 1, 100 ).Select( i => i + [last result] );
但是如果没有多行lambda并将结果存储在其他地方,我找不到这样做的方法。
因此,我在Linq能够做到的最好的斐波纳契总和是:
List<int> calculated = new List<int>( new int[] { 1, 2 });
var fibonacci = Enumerable.Range(2, 10).Select(i =>
{
int result = calculated[i - 2] + calculated[i - 1];
calculated.Add(result);
return result; // and how could I just put the result in fibonacci?
}
);
这看起来很难看。我可以使用常规的for循环在较少的代码中执行此操作。
for (int i = 2; i < 10; i++)
{
calculated.Add(calculated[i - 2] + calculated[i - 1]);
}
似乎我能找到一种方法来做到这一点,我可以使用Linq进行大量的线性编程并总结很多迭代公式。
答案 0 :(得分:6)
如果您正在寻找一种创建Fibonacci序列生成器的方法,那么最好编写自己的生成器函数,而不是使用Linq扩展方法。像这样:
public static IEnumerable<int> Fibonacci()
{
int a = 1;
int b = 0;
int last;
for (;;) {
yield return a;
last = a;
a += b;
b = last;
}
}
然后,您可以将Linq方法应用于此枚举,以实现您想要的结果(例如,尝试迭代Fibonacci().Take(20)
)。
Linq扩展方法不是每个编程问题的解决方案,我只能想象纯LINQ Fibonacci序列生成器看起来多么可怕。
答案 1 :(得分:1)
最接近你可以使用LINQ IEnumerable.Aggregate方法(函数式编程的折叠)来实现类似的东西。例如,您可以使用它来总结集合的方块,例如:
int sumSquares = list.Aggregate(0, (sum, item) => sum + item * item);
因为在LINQ中,使用枚举器从集合中检索值,即它们是逐个采用的,根据定义,没有&#34;前一项&#34;的概念。甚至可以使用一些yield return
魔法来动态生成和丢弃这些项目。也就是说,你总是可以使用一些黑客:
long a= 1;
long b= 1;
var fibonacci = Enumerable.Range(1,20).Select(i => {
long last= a + b;
b = a;
a = last;
return last;
});
但是当你必须使用和修改外部变量以使lambda工作时,你就处于代码嗅觉区域。