【问题标题】:c# List<Object> group by name and date calculate sum and average to List<Dictionary<string,string>>c# List<Object> 按名称和日期分组计算 List<Dictionary<string,string>> 的总和和平均值
【发布时间】:2015-07-06 01:08:08
【问题描述】:

如果我有课:

public class Custom
{
   public Custom()
   {

   }

   public DateTime TargetDate { get; set; }
   public string Name { get; set; }
   public decimal Price { get; set; }
   public decimal Value { get; set; }
}


List<Custom> customItems = new List<Custom>();

上面的列表可以包含任意数量的可以称为相同或不同的项目。这些项目可以在任何一天,甚至在一个特定日期称为相同的多个项目。

我如何使用 linq 按名称和日期对列表进行分组,并计算 sum 为财产价格和average 为财产价值。

所以基本上,结果应该是一个 List> 并且为每个分组名称 + 日期计算的属性。

这是我迄今为止尝试过的。

var aggdata = customItems.GroupBy(t => new { t.Name, t.TargetDate.Date })
              .ToDictionary(t => t.Key.Name, t => t.Sum(x => x.Price));

但我缺少字典中的平均值和日期值。

结果应该是这样的:

"TargetDate", "01.01.2015"
"Name", "SomeName"
"Value", "123"   // Average of values
"Price", "1234"  // Sum of price values

.........

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您可以投影到具有您需要的所有属性的匿名对象。如果您在多个日期都有该名称,那么该字典投影将是有问题的。您可能希望改为投影到 Lookup。这允许您拥有多个密钥。

    var aggdata = customItems.GroupBy(t => new { t.Name, t.TargetDate.Date })
              .ToLookup(t => t.Key.Name, t => new {
                  Date = t.Key.Date,
                  Average = t.Average(x => x.Value),
                  Sum = t.Sum(x => x.Price)
              });
    

    【讨论】:

    • 只是一个注释;如果您在同一日期有两个名字,这将失败(它将创建两个组,但尝试将重复的名字插入字典)。这实际上来自原始帖子的要求,但在我看来,关键应该是分组对象,而不是名称......但这取决于@user2818430的要求
    【解决方案2】:

    这对我有用:

    var query =
        from ci in customItems
        group ci by new { ci.TargetDate, ci.Name } into gcis
        select new Custom()
        {
            TargetDate = gcis.Key.TargetDate,
            Name = gcis.Key.Name,
            Price = gcis.Sum(x => x.Price),
            Value = gcis.Average(x => x.Value),
        };
    
    List<Custom> results = query.ToList();
    

    使用此示例数据:

    List<Custom> customItems = new List<Custom>()
    {
        new Custom() { TargetDate = DateTime.Now.Date, Name = "Foo", Price = 1m, Value = 2m, },
        new Custom() { TargetDate = DateTime.Now.Date, Name = "Foo", Price = 2m, Value = 4m, },
        new Custom() { TargetDate = DateTime.Now.Date, Name = "Bar", Price = 3m, Value = 8m, },
    };
    

    我得到了这些结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多