4

我本人是 LINQ 的忠实粉丝。简洁的艺术体现在 LINQ 中。同样在 .Net 中,我们说 LINQ 比循环领先一步,或者我们可以说 LINQ 是循环++。

但真的是这样吗?

为什么我要评判是因为我试图将这个 for 循环代码转换为 LINQ,但对 LINQ 跳过/离开索引感到困惑?

double[] NMD = {3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0 };

for(int i=1; i<NMD.Length-1; i+=2)
   NMD[i] = NMD[i]/10;

在这里,我要求循环从索引 1 开始并在倒数第二个值处停止,并且还将值跳过 2。所以我们可以在 LINQ 中执行此操作吗?IMO 我不这么认为但我很高兴被证明是错误的。

4

4 回答 4

5

您可以测试内部的索引Select并相应地选择您的操作:

NMD = NMD.Select((x, i) => i % 2 == 1 && i < NMD.Length - 1 ? x / 10 : x).ToArray();
// => { 3, 0.5, 6, 6.5, 34, 0.3, 5, 0.6, 65, 3.4, 3, 0.5, 6, 6.5, 34 }

但是,您可能已经通过查看此语句的大小了解到,LINQ在这里并不是概念上的改进,因为您只能使用它创建新序列,而不能改变现有序列。

也就是说for,在我看来,循环很好,实际上更具可读性。与其说“LINQ 是循环++”,不如说它是“LINQ 是序列生成++”或“只读迭代++”。

如果您想有效地使用 LINQ,您必须以更实用的方式重新思考和重新设计您的代码(例如,使用不可变的数据结构),而不是仅仅用forLINQ 表达式替换每个循环。如果您因此而明智地这样做,则可以提高代码的质量,并使将来的切换并行执行问题更少。

于 2012-04-21T10:40:18.537 回答
1
var NMD = new[] {3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0, 3.0, 5.0, 6.0, 65.0, 34.0 };
NMD = NMD.Select((n, i) => i % 2 == 1  ? n / 10 : n).ToArray();
于 2012-04-21T10:41:53.387 回答
0

您可以使用 仅选择具有奇数索引的项目NMD.Where((x,i) => i % 2 == 1),但您将无法更新数组中的值。

于 2012-04-21T10:38:15.180 回答
0

对于此类任务,Linq 并不是真正的最佳工具——就地更改数据,而且只是其中的一些。但如果你真的想这样做,你可以这样做:

NMD = NMD.Select((x, i) =>
{
    if (i < 1 || i >= NMD.Length - 1 || (i % 2)==0)
        return x;
    else
        return x / 10;
}).ToArray();

请记住,使用 linq,您不会更改现有序列,而是将其替换为新序列。

于 2012-04-21T10:45:08.327 回答