【发布时间】:2011-05-20 02:36:15
【问题描述】:
我有一个对象列表。单个对象条目的一个属性是数量。如何获得金额的总和?
如果我的列表是 double 类型,我可以这样做:
double total = myList.Sum();
但是我想要类似的东西,但是这个语法不正确。
double total = myList.amount.Sum();
我应该如何去完成这个?如果可能的话,我希望使用 Sum 函数,而不是循环并计算值。
【问题讨论】:
我有一个对象列表。单个对象条目的一个属性是数量。如何获得金额的总和?
如果我的列表是 double 类型,我可以这样做:
double total = myList.Sum();
但是我想要类似的东西,但是这个语法不正确。
double total = myList.amount.Sum();
我应该如何去完成这个?如果可能的话,我希望使用 Sum 函数,而不是循环并计算值。
【问题讨论】:
using System.Linq;
...
double total = myList.Sum(item => item.Amount);
【讨论】:
如果您需要对符合特定条件的项目执行此操作...
double total = myList.Where(item => item.Name == "Eggs").Sum(item => item.Amount);
【讨论】:
另一种选择:
myPlanetsList.Select(i => i.Moons).Sum();
【讨论】:
.Select(i => i.Moons).Sum()代替.Sum(i => i.Moons)
这是您可以运行以进行此类测试的示例代码:
var f = 10000000;
var p = new int[f];
for(int i = 0; i < f; ++i)
{
p[i] = i % 2;
}
var time = DateTime.Now;
p.Sum();
Console.WriteLine(DateTime.Now - time);
int x = 0;
time = DateTime.Now;
foreach(var item in p){
x += item;
}
Console.WriteLine(DateTime.Now - time);
x = 0;
time = DateTime.Now;
for(int i = 0, j = f; i < j; ++i){
x += p[i];
}
Console.WriteLine(DateTime.Now - time);
复杂对象的同一个例子是:
void Main()
{
var f = 10000000;
var p = new Test[f];
for(int i = 0; i < f; ++i)
{
p[i] = new Test();
p[i].Property = i % 2;
}
var time = DateTime.Now;
p.Sum(k => k.Property);
Console.WriteLine(DateTime.Now - time);
int x = 0;
time = DateTime.Now;
foreach(var item in p){
x += item.Property;
}
Console.WriteLine(DateTime.Now - time);
x = 0;
time = DateTime.Now;
for(int i = 0, j = f; i < j; ++i){
x += p[i].Property;
}
Console.WriteLine(DateTime.Now - time);
}
class Test
{
public int Property { get; set; }
}
我关闭编译器优化的结果是:
00:00:00.0570370 : Sum()
00:00:00.0250180 : Foreach()
00:00:00.0430272 : For(...)
第二个测试是:
00:00:00.1450955 : Sum()
00:00:00.0650430 : Foreach()
00:00:00.0690510 : For()
看起来 LINQ 通常比 foreach(...) 慢,但对我来说奇怪的是 foreach(...) 似乎比 for 循环快。
【讨论】:
System.Diagnostics中的Stopwatch,因为它是一个高性能的时间记录器。 (顺便说一句,我没有对你投反对票)
DateTime.Now 进行测量。它的性能很糟糕,因为它总是返回当地时间。 DateTime.UtcNow 更快;但是,它仍然没有像Stopwatch 类那样使用高分辨率。