【问题标题】:C# List of objects, how do I get the sum of a propertyC#对象列表,我如何获得一个属性的总和
【发布时间】:2011-05-20 02:36:15
【问题描述】:

我有一个对象列表。单个对象条目的一个属性是数量。如何获得金额的总和?

如果我的列表是 double 类型,我可以这样做:

double total = myList.Sum();

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

double total = myList.amount.Sum();

我应该如何去完成这个?如果可能的话,我希望使用 Sum 函数,而不是循环并计算值。

【问题讨论】:

    标签: c# list sum


    【解决方案1】:
    using System.Linq;
    

    ...

    double total = myList.Sum(item => item.Amount);
    

    【讨论】:

    • 出于兴趣,这比 foreach 快吗?
    • 我也对@CodeBlend 的问题感兴趣。这种计算会比 for 循环更快吗?
    • @Coops - 回答您的问题...使用包含 100,000 个对象的列表,每个对象具有双精度数据类型的单个属性,使用上述解决方案 (myList.Sum) 对属性求和 1,000 次2.44 秒,而使用 foreach 为 0.98 秒。使用秒表类测量经过的时间以确保准确性。因此 foreach 比使用 myList.Sum 快 2 倍以上。
    • Linq 永远不会比纯 foreach 快。仅在方便、时间不紧迫的地方使用。
    【解决方案2】:

    如果您需要对符合特定条件的项目执行此操作...

    double total = myList.Where(item => item.Name == "Eggs").Sum(item => item.Amount);
    

    【讨论】:

      【解决方案3】:

      另一种选择:

      myPlanetsList.Select(i => i.Moons).Sum();
      

      【讨论】:

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

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

      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 类那样使用高分辨率。
      • 这不能回答问题。
      • 好的,谢谢提示。分数是非常可重复的,所以我认为这样的分辨率就足够了
      • 虽然你的意图是好的——马克是对的——你并没有明确地回答这个问题。我建议您将其更改为:“这是你可以做到的”和“这是每个选项的 cpu 性能”。同样原则上,如果您描述了您的测试方法,则无需向我们展示代码。
      猜你喜欢
      • 2021-12-21
      • 2021-06-15
      • 1970-01-01
      • 2019-12-16
      • 2019-10-09
      • 2013-08-17
      • 1970-01-01
      • 2022-01-24
      • 2014-02-09
      相关资源
      最近更新 更多