Nikhil Agrawal
Nikhil Agrawal

Reputation: 48560

Can LINQ be asked to Skip/Leave particular indexes?

I myself am a big fan of LINQ. The art of brevity is reflected in LINQ. Also in .Net we say that LINQ is a step ahead of loops or we can say LINQ is loops++.

But is it really this way?

Why i am being judgmental is because i was trying to convert this for loop code to LINQ but was confused that do LINQ skip/Leave indexes?

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;

Here i am asking for loop to start from index 1 and stop at the penultimate value and also skip value by 2. So can we do this in LINQ. IMO I don't think so But I'll be happy to be proven wrong.

Upvotes: 4

Views: 2729

Answers (4)

Niklas B.
Niklas B.

Reputation: 95328

You can test the index inside Select and choose your action accordingly:

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 }

However, as you maybe already figured out by looking at the size of this statement, LINQ is not a conceptual improvement here, because you can only create new sequences with it and not mutate existing sequences.

That said, the for loop is fine and actually more readable, in my opinion. Rather than saying that "LINQ is loops++", you should refine it to "LINQ is sequence generation++" or "read-only iteration++".

If you want to use LINQ efficiently, you have to rethink and redesign your code in a more functional way (and use immutable data structures, for example) instead of just replacing every for loop with a LINQ expression. If you do that consequently and sensibly, you can increase the quality of your code and make the switch parallel execution less problematic in the future.

Upvotes: 5

Sergey Podolsky
Sergey Podolsky

Reputation: 157

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

Upvotes: 1

voidengine
voidengine

Reputation: 2579

Linq is not really the best tool for this kind of task - changing data inplace, and only some of them. But if you really want to, you can do it like this:

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

Remember that with linq, you won't change the existing sequence, you'll replace it with a new one.

Upvotes: 0

Oliver Hanappi
Oliver Hanappi

Reputation: 12346

You can select only items with odd indices with NMD.Where((x,i) => i % 2 == 1), but you won't be able to update the values in the array.

Upvotes: 0

Related Questions