2013-03-08 3 views
4

Привет всем,Проблема в Linq объекта, где положение: условие обойдена

Сегодня это мой первый пост на моем любимом # помогая RESSOURCES веб-сайт C. Я хочу присоединиться к сообществу.

Вот моя проблема, я бы хотел вызвать. Выберите предложение linq, чтобы создать список структуры после фильтрации списка двойных значений с помощью предложения .Where, но условия фильтрации, похоже, не оцениваются, или они return всегда истинно.
Пожалуйста, просмотрите мой код, чтобы хорошо понять проблему:

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

Возможно, я неправильно понял использование Linq, но в конце концов вернулся BufferInfo [] содержит все значения в то время как есть некоторые значения меньше, чем 1,0 в lenValues массив. Для информации нет параллельного доступа к этому кодовому блоку. Локальные переменные в блоке linq обычно инициализируются динамически (перенастраиваются внешней сборкой из National Instruments), она здесь только для вас.

Например, тот же bahaviour но для цикла, работает хорошо:

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

Я не хочу использовать LINQ или нет, я просто хочу, чтобы понять, почему это не удается.
Пожалуйста, объясните мне, почему у меня такие странные результаты.

С уважением,
Lun @ ir.

+2

Используйте цикл 'for'. Это, возможно, более ясное, чем версия Linq в этом случае, и вы вставляете мутацию в свой 'Select', который не соответствует стандартным ожиданиям Linq (который он фильтрует, проекты, агрегаты и т. Д., Но в противном случае оставляет исходный код данные не изменены). –

+0

Энтони прав; делая предложение select, которое * изменяет материал *, является худшей практикой. Запрос должен просто * задавать вопросы * о данных, он не должен * изменять * данные. –

ответ

2

Ну, это потому, что ваш .Select((c, it) => начинает свой индекс от 0 снова ...

Так что, если ваша статья Where фильтрует элементы и возвращает только 4 пунктов, ваш Select будет использовать индексы 0, 1, 2, 3, которые не соответствуют индексам предметов, которые вы вернули с Where.

+0

Хорошо, думаю, я понял свою ошибку. Большое спасибо !! – lunair

1

Ваш код даже не компилируется, так что я понятия не имею, как Вы проверили, что это не работает ...

Вы должны написать Select получить индексы первого, а затем передать его в Where метод:

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

Этот код возвращает 4 значения, что является предикативным и представляется правильным результатом.

+0

Существует метод расширения с индексом в качестве параметра ... – lunair

+0

Да, только что осознал это. Обновлен мой ответ. – MarcinJuraszek

+0

Замените BufferInfo [] на var и «return new Buffer» на «return new» – lunair

Смежные вопросы