2013-02-07 68 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; 
            });