Linq problem for where where object: condition bypasses

Hello to all,

Today is my first post on my favorite C # website. I wish to join the community.

Here is my problem, I would like to call. Select the linq clause to create a list of structures after filtering the list of double values โ€‹โ€‹with the .Where clause, but the filter conditions do not look evaluated or they are always returned correctly.
Please review my code to understand the problem:

string[] msgNames = new string[] { "de", "vf", "ze", "ki", "vt", "er" }; double[] prevCounters = new double[] { 154.0, 24588.0, 4547.0, 788.0, 1455.0, 24577.0 }; double[] counters = new double[] { 8548.0, 54854.0, 54854.0, 44.0, 121.0, 48547.0 }; double[] lenValues = new double[] { 1.0, 2.0, 0.0, 4.0, 5.0, 0.0 }; BufferInfo[] positiveLenValues = counters .Where((c, it) => lenValues[it] >= 1.0 && prevCounters[it] != c) .Select((c, it) => { prevCounters[it] = c; return new BufferInfo() { Name = msgNames[it], Length = lenValues[it] }; }).ToArray(); 

Perhaps I misunderstood the use of linq, but at the end, the returned BufferInfo [] contains all the values, while the lenValues โ€‹โ€‹array has values โ€‹โ€‹less than 1.0. For information, there is no parallel access to this code block. Local variables above the linq block are usually dynamically initialized (reconfigured by an external assembly from National Instruments), here is just for you.

For example, the same bahaviour works, but with a for loop:

 List<BufferInfo> myInfos = new List<BufferInfo>(); for (int i = 0; i < 6; i++) { if (lenValues[i] >= 1.0 && prevCounters[i] != counters[i]) { oldCounters[i] = counters[i]; myInfos.Add(new BufferInfo() { Length = lenValues[i], Name = msgNames[i] }); } } BufferInfo[] buffers = myInfos.ToArray(); 

I do not want to use linq or not, I just want to understand why it fails.
Please explain to me why I have such strange results.

Yours faithfully,
Lun @ l.

+4
source share
2 answers

Good, because your .Select((c, it) => starts its index again from 0 ...

So, if your Where clause filters the elements and returns only 4 elements, your Select will use the indices 0, 1, 2, 3 , which do not match the indices of the elements that you returned with Where .

+2
source

Your code doesn't even compile, so I have no idea how you tested it, that it doesn't work ...

You need to write Select to get the indexes first and then pass it to the Where method:

 BufferInfo[] positiveLenValues = counters.Select((c, i) => new { c, i }) .Where(e => lenValues[ei] >= 1.0 && prevCounters[ei] != ec) .Select(e => { prevCounters[ei] = ec; return new BufferInfo { Name = msgNames[ei], Length = lenValues[ei] }; }).ToArray(); 

This code returns 4 values, which is predictable and seems to be the correct result.

+1
source

All Articles