2012-12-26 44 views
3

我想找到一种方法来访问同一行中的Linq方法的以前的值。与Linq迭代

我希望能够在LINQ to使用一般形式:

var values = Enumerable.Range(1, 100).Select(i => i + [last result]); 

但我不能找到一种方法,做这样的事情没有多行拉姆达的和存储的结果在其他地方。

所以最好的总和斐波纳契我已经能够在LINQ to做的是:

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做了很多的线性规划,总结了很多迭代公式。

+8

LINQ是缩写词的最后一个字母,代表查询。不是为了计算......不要把它硬塞进它不是的东西。 – Oded

+0

@Oded:那可能是“答案”。我仍然在努力学习Linq的界限。我可以想到2次面试,我可以说你做了什么(尽管温和一点)。你能提交这个答案吗? – micahhoover

回答

6

如果您正在寻找创建斐波那契序列生成器的方法,那么最好是编写自己的生成器函数,而不是使用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

方形挂钩,圆孔和所有...... – Oded

+0

我不认为使用发生器模式产生无限序列是将方形挂钉放入圆孔中。事实上,它可能相当有用。 – cdhowie

+2

Howie - 我的评论是关于最后一句话的,特别是“Linq扩展方法不是每个编程问题的解决方案”。我同意了。 – Oded

1

最接近LINQ的是IEnumerable.Aggregate方法(函数式编程也称为折叠)。您可以使用它,例如,总结收集的广场,如:

int sumSquares = list.Aggregate(0, (sum, item) => sum + item * item); 

由于LINQ的值从集合使用枚举,即它们采取一个接一个,顾名思义检索,没有“上一个项目”的概念。这些物品甚至可以在飞行中生成并丢弃,使用一些神奇的魔法。这就是说,你总是可以使用一些黑客一样:

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表达式工作的那一刻,你在代码气味的领土。

+0

我不喜欢他们因为某种原因选择了名称聚合。不知何故,它使得生成的表达式对我来说不那么优雅。 – ChaosPandion