简体   繁体   English

通过DateTime属性遍历列表

[英]Iterating through list by DateTime property

I have a List and I need to calculate average of Value for each day by Created. 我有一个列表,我需要通过Created计算每天的平均价值。 How can I elegantly iterate the list for each day presented in the list? 我如何优雅地迭代列表中列出的每一天的列表? There can be gaps in the days and varying number of objects for each day. 每天可能会有间隔,每天的对象数量会有所不同。

For example values could be something like these: 例如,值可能是这样的:

public class MyObject
{
    public double Value { get; set; }
    public DateTime Created { get; set; }
}

{ Value: 1, Created: 2018-07-01 12:00:00 }
{ Value: 4, Created: 2018-07-01 20:00:00 }
{ Value: 2, Created: 2018-07-03 12:00:00 }
{ Value: 3, Created: 2018-07-04 09:00:00 }
{ Value: 2, Created: 2018-07-04 11:00:00 }
{ Value: 6, Created: 2018-07-04 12:00:00 }
{ Value: 5, Created: 2018-07-06 16:00:00 }
{ Value: 3, Created: 2018-07-06 11:00:00 }

I could go for something like this... 我可以去这样的东西...

List<MyObject> items = itemsfrombackend;
DateTime beginDay = items.First().Created;
DateTime endDay = items.Last().Created;
for (DateTime day = beginDay; day <= endDay; day.AddDays(1))
{
    // if items contains any matching objects calculate avg
}

But would like to find a simpler way with less ifs 但是想找到一个更少的ifs的简单方法

I would use a GroupBy() combined with Average() 我会结合使用GroupBy()Average()

var result = items.GroupBy(x => x.Created.Date)
                  .Select(x => new { Created = x.Key, Avg = x.Average(y => y.Value) });

You can use LINQ to group the data and calculate averages. 您可以使用LINQ对数据进行分组并计算平均值。 You can use DateTime.Date to retrieve the date part of a DateTime value,eg : 您可以使用DateTime.Date检索DateTime值的日期部分,例如:

var averages=items.GroupBy(grp=>grp.Created.Date)
        .Select(grp=>new {Date=grp.Key,Average=grp.Average(it=>it.Value)});

Or in query form: 或以查询形式:

var averages=from item in items
             group item by item.Created.Date into grp
             select new { Date=grp.Key,
                          Average=grp.Average(it=>it.Value)
                        };

GroupBy creates a "bucket" of items that share the same key. GroupBy创建一个共享相同密钥的项目的“存储桶”。 That bucket can be treated as a collection, allowing you to filter it, pick individual items or calculate aggregate functions based on its contents, like Averabe() . 该存储桶可以视为一个集合,使您可以对其进行过滤,选择单个项目或根据其内容计算聚合函数,例如Averabe()

Many of the One of the Average() overloads allow you to specify the property you want to use for the calculation. 多个Average()重载之一使您可以指定要用于计算的属性

grp.Average(it=>it.Value)

Selectes and averages the contents of the Value of the items found in each group's bucket 选择并平均每个组的存储桶中找到的项目的Value的内容

You can solve it completely using LINQ as others mentioned. 如其他人所述,您可以使用LINQ完全解决它。 You can try this method too, which has some LINQ ;-) 您也可以尝试这种方法,它具有一些LINQ ;-)

Dictionary<DateTime, decimal> avg = new Dictionary<DateTime, decimal>();

foreach (MyObject obj in items)
{
    if (avg.ContainsKey(obj.Created.Date))
    {
        avg[obj.Created.Date] += (decimal)obj.Value;
    }
    else
    {
        avg.Add(obj.Created.Date, (decimal)obj.Value);
    }
}

foreach (var item in avg.ToList())
{
    avg[item.Key] =Math.Round(item.Value / items.Count(x => x.Created.Date == Convert.ToDateTime(item.Key).Date),1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM