如何以较小的时间增量过滤集合? [关闭]

问题描述 投票:-2回答:1

给定一个如下所示的集合:

[
{Price:123.45, DateTime:01/01/18 12:01:10}
{Price:89.23, DateTime:01/01/18 12:01:20}
{Price:66.13, DateTime:01/01/18 12:01:30}
{Price:75.00, DateTime:01/01/18 12:02:45}
]

如何使用linq过滤此集合,仅包含最接近每分钟开头的第一个数据项?例如,我想将上面的集合转换为以下集合:

[
{Price:123.45, DateTime:01/01/18 12:01:10}
{Price:75.00, DateTime:01/01/18 12:02:45}
]

另外,我如何实现类似的解决方案,而不是过滤集合以包括最接近每分钟开始的第一个数据项,我想包括最接近每个5分钟间隔开始的第一个数据项?例如,最接近的数据项是12:00,12:05,12:10等?

c# .net linq
1个回答
1
投票

第一个问题最简单的解决方案是:

items.GroupBy(x => x.DateTime.AddSeconds(-x.DateTime.Second))
     .Select(x => x.OrderBy(i => i.DateTime).First());

然后我尝试制作可重复使用的解决方案,让您设置任何时间间隔:

public static IEnumerable<Item> ClosestTo(IEnumerable<Item> items, TimeSpan interval)
{
    return items.GroupBy(item =>
    {
        // Find a date that is closest to the start of interval.
        var ticksFloor = item.DateTime.Ticks - (item.DateTime.Ticks % interval.Ticks);
        return new DateTime(ticksFloor);
    }).Select(grouping => grouping.OrderBy(item => item.DateTime).First());
}

例:

var items = new List<Item>
{
    new Item { DateTime = DateTime.Parse("01/01/18 12:01:10") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:01:20") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:01:30") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:02:45") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:05:00") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:07:30") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:09:00") },
    new Item { DateTime = DateTime.Parse("01/01/18 12:14:00") }
};

foreach (var item in ClosestTo(items, TimeSpan.FromMinutes(5)))
{
    Console.WriteLine($"DateTime: {item.DateTime}");
}

输出是:

日期时间:01.01.2018 12:01:10 日期时间:01.01.2018 12:05:00 日期时间:01.01.2018 12:14:00

© www.soinside.com 2019 - 2024. All rights reserved.