C#对象列表,如何获取属性的总和

Jos*_* U. 145 c# sum list

我有一个对象列表.单个对象条目的一个属性是金额.我如何得到金额的总和?

如果我的列表是double类型,我可能会做这样的事情:

double total = myList.Sum();
Run Code Online (Sandbox Code Playgroud)

但是我想要类似的东西,但这种语法是不正确的.

double total = myList.amount.Sum();
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?我希望尽可能使用Sum函数,而不是循环并计算值.

Ale*_* LE 277

using System.Linq;
Run Code Online (Sandbox Code Playgroud)

...

double total = myList.Sum(item => item.Amount);
Run Code Online (Sandbox Code Playgroud)

  • @Coops - 要回答你的问题...使用包含100,000个对象的列表,每个对象具有数据类型为double的单个属性,使用上面的解决方案(myList.Sum)将属性总计1,000次需要2.44秒,而使用foreach需要0.98秒.使用秒表类测量经过的时间是为了准确.因此,foreach比使用myList.Sum快2倍. (14认同)
  • 这比foreach更快吗? (11认同)
  • Linq 永远不会比纯 foreach 更快。仅在方便、时间不紧迫的地方使用它。 (5认同)
  • 我也对@ CodeBlend的问题感兴趣.这个计算会比for循环更快吗? (4认同)

Gre*_*inn 32

如果你需要在符合特定条件的物品上进行...

double total = myList.Where(item => item.Name == "Eggs").Sum(item => item.Amount);
Run Code Online (Sandbox Code Playgroud)


use*_*Bee 9

另一种选择:

myPlanetsList.Select(i => i.Moons).Sum();
Run Code Online (Sandbox Code Playgroud)

  • 而不是```.Select(i => i.Moons).Sum()```你可以使用```.Sum(i => i.Moons)``` (4认同)
  • @Mason,对,这就是 Alex 在他之前的回答中解决问题的方式,所以我只是提供了一种不同的方式来做同样的事情。 (3认同)
  • 我很欣赏这是一个独特的答案,但是性能不会受到影响吗? (2认同)

Puc*_*acz 5

以下是您可以运行来进行此类测试的示例代码:

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);
Run Code Online (Sandbox Code Playgroud)

复杂对象的相同示例是:

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; }
}
Run Code Online (Sandbox Code Playgroud)

关闭编译器优化后我的结果是:

00:00:00.0570370 : Sum()
00:00:00.0250180 : Foreach()
00:00:00.0430272 : For(...)
Run Code Online (Sandbox Code Playgroud)

第二个测试是:

00:00:00.1450955 : Sum()
00:00:00.0650430 : Foreach()
00:00:00.0690510 : For()
Run Code Online (Sandbox Code Playgroud)

看起来 LINQ 通常比 foreach(...) 慢,但对我来说奇怪的是 foreach(...) 似乎比 for 循环更快。

  • 这并不能回答问题。 (3认同)
  • 为了便于将来参考,请查看“System.Diagnostics”中的“Stopwatch”,因为它是一个高性能时间记录器。(顺便说一句,我没有对你投反对票) (2认同)
  • 虽然你的意图是好的——马克是对的——但你并没有明确回答这个问题。我建议你将其更改为:“这是你可以如何做到这一点”和“这是每个选项的CPU性能”。同样原则上,如果您描述了您的测试方法,则无需向我们展示代码。 (2认同)