LINQ可以被要求跳过/离开特定索引吗?

时间:2012-04-21 10:34:25

标签: c# .net linq loops

我自己是LINQ的忠实粉丝。 LINQ反映了简洁的艺术。同样在.Net中我们说LINQ比循环领先一步,或者我们可以说LINQ是循环++。

但这是真的吗?

为什么我的判断力是因为我试图将这个转换为循环代码转换为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 个答案:

答案 0 :(得分: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 is sequence generation ++”或“read-only iteration ++”,而不是说“LINQ is loops ++”。

如果您想有效地使用LINQ,您必须以更实用的方式重新思考和重新设计代码(例如,使用不可变数据结构),而不是仅使用LINQ表达式替换每个for循环。如果您这样做并且理智,那么您可以提高代码质量,并使交换机并行执行在未来不那么成问题。

答案 1 :(得分: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();

答案 2 :(得分:0)

您只能选择带有NMD.Where((x,i) => i % 2 == 1)奇数索引的项目,但您将无法更新数组中的值。

答案 3 :(得分: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,您不会更改现有序列,而是将其替换为新序列。