2013-02-07 69 views
1

我有一個具有整數屬性的類。我有一份要在圖表應用程序中使用的列表。我想將此屬性顯示爲累計總數,同時保留所有其他班級信息。使用Linq Aggregate或ForEach更新運行總數的屬性

我們稱之爲ProgressMeasurement,屬性爲OutstandingItems。有什麼方法,使用聚合函數,我可以做到這一點?

例如:

progressMeasurementList.Aggregate((a, b) => b.OutstandingItems += a.OutstandingItems)); 

即我想更新b的OutstandingItems值是當前運行總數。

乾杯

+0

你是說,你要與列表更新項目的屬性運行總數? – juharr

+0

@juharr是的,正好。 –

回答

1

沒有什麼內置的,但你可以創建自己的擴展方法:

public static IEnumerable<TAccum> Scan<T, TAccum>(this IEnumerable<T> seq, TAccum init, Func<TAccum, T, TAccum> op) 
{ 
    TAccum current = init; 
    foreach(T item in seq) 
    { 
     current = op(current, item); 
     yield return current; 
    } 
} 

然後可以計算累計和的順序如下:

var runningTotals = progressMeasurementList.Scan((acc, b) => acc + b.OutstandingItems)); 
+0

爲什麼不使用Aggregate? – gabba

+2

@gabba由於「Aggregate」的概念是通過對序列中所有值使用組合操作來生成一個單一值。他不想生成單個值,他想生成一個新的值序列,因此它不適用。 – Servy

+0

-1這並沒有解決將運行總數設置爲每個項目的屬性的問題。 – juharr

0

這將是.Sum()方法:

var sum = progressMeasurementList.Sum(prog => prog.OutstandingItems);

+0

這會給我一個完整的總數,而不是總數。 –

0

我會在foreach那樣做。不應該使用Linq查詢來更改源代碼。

var runningTotal = progressMeasurementList.First().OutstandingItems; 
foreach(var progressMeasurement in progressMeasurementList.Skip(1)) 
{ 
    runningTotal += progressMeasurement.OutstandingItems; 
    progressMeasurement.OutstandingItems = runningTotal; 
} 
0

也許要晚,但蔭添加此

int total = 0; 
    t.Aggregate(total, (acc, current) => 
     { 
      acc+= current.OutstandingItems; 
      current.CumulativeOutstandingItems = acc; 
      return acc; 
     }); 

值得注意的總變種:我不`噸知道你要替換累計總和或不OutstandingItems。爲了可讀性,我在不同的屬性中添加了總和。

+1

1)使用'Aggregate'的全部重點是它佔據了你的總數,你不需要創建你自己的。這就是'acc'在這裏。 2)通常最好避免LINQ操作中的副作用;它專爲*查詢*而設計,不會修改數據。 – Servy

+0

1.在這個例子中,這個總數用於更新。 2.你完全正確 – gabba

+1

1)我說你不需要。它已經存在,'Aggregate'方法正在創建變量,根據需要進行更新,並將其提供給您用於您的方法(提供您使用適當的過載)。以這種方式使用封閉是不可取的。實際上,它很難證明它是有效的,而且它對環境或用法的變化要脆弱得多。 – Servy

1

Linq針對查詢而不是更新。更新通常與傳統的循環清潔劑:

var runningTotal = 0; 
foreach(var item in progressMeasurementList) 
{ 
    runningTotal += item.OutstandingItems 
    item.OutstandingItems = runningTotal)); 
} 
+0

謝謝,我明白你的意思了。 –

0

你可以嘗試使用ForEach方法,像這樣:

int runningTotal = 0; 
progressMeasurementList.ForEach(item => 
            { 
             runningTotal += item.OutstandingItems; 
             item.OutstandingItems = runningTotal; 
            });