2016-02-17 3 views
0

Я хотел бы вычислить sth, как разницу в скорости с linq в списке, но не могу заставить его работать.Изменение значения на основе критериев с LINQ

Вот что я пытаюсь сделать (упрощение версии):

public class SampleCl 
{ 
    public string label; 
    public double val; 
    public double valdiff; 
} 

У меня есть класс со значениями и метка и третий двойной с предполагается провести различие.

Некоторые образцы данных:

 var samplelist = new List<SampleCl>(); 
     samplelist.Add(new SampleCl {label ="A", val= 1 }); 
     samplelist.Add(new SampleCl { label = "B", val = 2 }); 
     samplelist.Add(new SampleCl { label = "C", val = 3 }); 

Приведенный ниже код не работает, но показывает хорошо, что я хочу сделать:

 samplelist.Where(a => a.valdiff = a.val - a.val.Where(a.label=="B")); 

valdiff должен чем держать -1, 0, 1 для A, B , C соответственно

+4

Linq не предназначена для мутирует. Вам лучше сделать это в «foreach». – juharr

+0

Я не уверен, понимаю ли вы, что вы имеете в виду. Вы хотите выбрать все значения различий из вашего списка образцов в элемент с помощью метки: label = B – HimBromBeere

+0

@HimBromBeere: Я хотел бы использовать значение с меткой «B» для вычитания и вычитать это из всех значений и сохранить результат в валдифе. – nik

ответ

4

Если вы действительно хотите сделать это в одной строке, вам необходимо использовать метод .
Но на мой взгляд это ничем не лучше, чем простой цикл Еогеасп и более слабым с точки зрения контроля на наличие базовой величины, используемой для вычисления разницы

samplelist.ForEach(x => x.valdiff = 
         (x.val - samplelist.FirstOrDefault 
           (s => s.label== "B").val)); 

Вместо простой цикл Еогеасп бы быть намного проще, понятнее и позволит вам ввести точную проверку присутствия элемента с ключевым значением.

// Assuming that you want to use zero if the item with label == B doesn't exist 
double num = 0; 
SampleCl baseItem = samplelist.FirstOrDefault(s => x.label == "B"); 
if(baseItem != null) num = baseItem.val; 
foreach(var item in samplelist) 
    item.valdiff = item.val - num; 
+2

Технически 'ForEach' не Linq. Это всего лишь метод 'List '. – juharr

+1

'ForEach' не является методом расширения. Это конкретный метод в «List ». – juharr

+0

@juharr снова вы правы, это много говорит о том, как часто я использую этот метод. – Steve

2

Там вы идете с помощью foreach.

samplelist.ForEach(s => s.valdiff = s.val - samplelist.Single(b => b.label == "B").val); 
+0

спасибо. в чем разница между одиночными и первыми/firstordefault pls? – nik

+2

Одинокий будет генерировать исключение, если элемент, удовлетворяющий условию, не найден. – HimBromBeere

+0

и firstordefault будет использовать ноль в качестве значения по умолчанию, если val является двойным? – nik

3

Я думаю, вы хотите сделать что-то подобное.

var b = samplelist.First(a => a.label=="B"); 
foreach(var samp in samplelist) 
    samp.valdiff = samp.val - b.val; 
1

Я предполагаю, что это может работать:

var val = sampleList.Single(x => x.label == "B").val; 
sampleList = sampleList.Select(x => new SampleCl 
    { 
     label = x.label, 
     val = x.val, 
     valdiff = x.value - val 
    }).ToList(); 
+1

Хотя это верный пример, я бы предпочел не использовать его. Это в основном то же самое, что и все другие решения здесь, но с дополнительным шагом воссоздания списка. В этом простом решении это не имеет значения, но если вы работаете с гораздо большим набором данных, это будет иметь огромное значение в производительности. –

0

Если вы хотите использовать LINQ только есть это единственная возможность сделать это:

var result = from a in samplelist 
       let b = samplelist.FirstOrDefault(b => b.label == "B") 
       let ab = a.valdiff = a.val - b.val 
       select a; 
+0

Мутирование в запросе Linq - чистое зло. – juharr

+0

Это не что иное, как samplelist.ForEach (....)! Я просто ответил на вопрос в соответствии с требованиями! –

+0

Обратите внимание, что этот код фактически не изменяет исходный список до тех пор, пока вы не выполните итерацию 'result'. – juharr

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