iT邦幫忙

0

C# lambda Sum and Divide

deh 2021-03-23 10:26:411258 瀏覽

各位前輩好

var sumA = table.Sum(s => s.columnA);
var sumB = table.Sum(s => s.columnB);
var target = sumA/sumB;

請問target可以用一行Lambda寫出來嗎?上面用了三行。

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

4
japhenchen
iT邦超人 1 級 ‧ 2021-03-23 10:48:03
最佳解答
var target = table.Sum(s => s.columnA/s.columnB) ;
看更多先前的回應...收起先前的回應...

沒檢查除零錯誤,是大忌....
弄個try...catch...處理

try{
    var target = table.Sum(s => s.columnA/s.columnB) ;
}
catch(Except ex){
    Console.WriteLine(ex.Message);
}
YoChen iT邦研究生 1 級 ‧ 2021-03-23 11:03:24 檢舉

這個會有錯哦!
(A1+B1+C1) / (A2+B2+C2) != A1/A2 + B1/B2 + C1/C2

lambda是each的委派沒錯吧?
所以.sum(s=>s.a/s.b)的狀況就是

var sum = 0;
foreach(var row in table){
    s += row.A / row.B;
}

我試了幾個表都是這個結果https://ithelp.ithome.com.tw/upload/images/20210323/201179547ymJazhqGw.jpg

deh iT邦研究生 1 級 ‧ 2021-03-23 11:31:27 檢舉

感謝回覆
sum(s=>s.a/s.b)是上述那樣沒錯
不過想求的是像下面那樣的

var sA = 0;
var sB = 0;
foreach(var row in table){
    sA += row.A;
    sB += row.B;
}
var target = sA/sB;
//這樣的結果跟sum(s=>s.a/s.b)不同

所以樓主的題意是有梗的
那只有

double target = (double)(table.Sum(s => s.columnA) / table.Sum(s => s.columnB));

也是一行

但求出的結果是全部列的平均,不是平均總和

Row1 : A 12   B 3  A/B = 4
Row2 : A 10  B 5  A/B = 2
Row3 : A 24  B 4  A/B = 6

SUM(Row1:Row3) = 12
SUM(A) / SUM(B) = 46 / 12 = 3.8333 
(total Average)?
YoChen iT邦研究生 1 級 ‧ 2021-03-23 12:19:17 檢舉

如果要用一行寫出來的話,解法應該就如同japhenchen大大後面提供的解法那樣~

var target = table.Sum(s => s.columnA) / table.Sum(s => s.columnB)

如果要求小數點後的值,則需要個別轉double以後再相除

var target = (double)table.Sum(s => s.columnA) / (double)table.Sum(s => s.columnB)

不過老實說這樣的解法我覺得跟原本樓主的三行沒什麼差異XDDD
主要因為除法只做一次,而並非每次都做
所以相除並不能進到lambda裡面,
才導致解法只能像上面一樣改變不大。

我要發表回答

立即登入回答