2016-02-17 87 views
0

我想計算某物與列表上的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

我不確定我是否明白你的意思。你是否想從樣本列表中選擇所有的差異值到標籤= B – HimBromBeere

+0

@HimBromBeere:我想使用帶有標籤「B」的值作爲一個減法運算符,並從所有值中扣除它並存儲結果在valdiff。 – nik

回答

4

如果你真的想在一行中做到這一點,那麼你需要使用方法。
但在我看來這是沒有辦法比簡單的foreach循環更好,更弱在用於計算差異

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

而不是一個簡單的foreach循環將基準值的存在控制方面要簡單得多,更容易理解,並且可以讓你引入對關鍵值存在的項目進行檢查。

// 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

如果找不到滿足條件的元素,則Single將拋出異常。 – 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