根据秒数范围从List <t>创建子集List <t>

时间:2018-02-08 18:11:17

标签: c# list lambda

我希望我能解释清楚。我有一个&#34;记录&#34;的列表。每条记录都有一个DateTime属性。我想要做的是创建另一个列表,其中包含&#34; X&#34;几秒钟。我试图使用lambda来做到这一点,但无法解决这个问题。请帮助一些人。请参阅演示代码。

public MainWindow()
{
    InitializeComponent();

    List<MyRecords> MyRecordsList = new List<MyRecords>();
    List<MyGroupedRecords> MyGroupedRecordsList = new List<MyGroupedRecords>();

    int groupRecordsThatAreSecondsApart = 3;

    MyRecords myRecord = new MyRecords() { Name = "A", RecordDate = new DateTime(2018, 2, 8, 0, 1, 0) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "B", RecordDate = new DateTime(2018, 2, 8, 0, 1, 1) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "C", RecordDate = new DateTime(2018, 2, 8, 0, 1, 19) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "C", RecordDate = new DateTime(2018, 2, 8, 0, 1, 4) };
    MyRecordsList.Add(myRecord);

    myRecord = new MyRecords() { Name = "W", RecordDate = new DateTime(2018, 2, 8, 2, 1, 10) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "X", RecordDate = new DateTime(2018, 2, 8, 3, 16, 31) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "Y", RecordDate = new DateTime(2018, 2, 8, 2, 1, 11) };
    MyRecordsList.Add(myRecord);
    myRecord = new MyRecords() { Name = "Z", RecordDate = new DateTime(2018, 2, 8, 2, 1, 14) };
    MyRecordsList.Add(myRecord);
}  

class MyRecords
{
    public string Name { get; set; }
    public DateTime RecordDate { get; set; }
}

class MyGroupedRecords
{
    public DateTime StartDate { get; set; }
    public List<MyRecords> GroupedRecordsList { get; set; }
}

我试图使用这样的东西,但无法解决这个问题:

List<GroupedSamples> groupedSamples = tag.SamplesCollection
    .GroupBy(r => r.StartTime)
    .Select(gg => new GroupedSamples 
    { 
        TimeStamp = gg.Key, 
        Samples = gg.OrderBy(r => r.StartTime).ToList(), 
        Count = gg.Count() 
    })
    .ToList();

2 个答案:

答案 0 :(得分:2)

您有两种选择:

您需要自己计算列表的笛卡尔积(您可以使用SelectMany来执行此操作),然后简单地比较所显示的两个日期时间值(对于任何低 - 低的对,因此您只检查产品的一半)。

或者您需要对列表进行排序,然后在其上使用滑动窗口(队列)来保留项目,直到第一个项目远离您要查找的时间间隔。当您读取每个新值时,扫描队列以查找有效的值,然后将其添加到末尾,如果开头的项目时间太远,请将它们从队列的前面删除。

对于内存中的小列表,我采用第一种方法,对于数据库查询,我会选择后者。

答案 1 :(得分:1)

我倾向于像这样实现它:

TimeSpan maxSpan = new TimeSpan(0, 0, groupRecordsThatAreSecondsApart);    
MyGroupedRecords group = null;
List<MyGroupedRecords> groups = new List<MyGroupedRecords>();

foreach (var record in MyRecordList.OrderBy(r => r.RecordDate))
{
    if (group == null || ((record.RecordDate - group.StartDate).CompareTo(maxSpan) > 0)) {
        // create a new group
        group = new MyGroupedRecords() { StartDate = record.RecordDate, Records = new List<MyRecords>() };
        groups.Add(group);
    }
    group.Records.Add(record);
}