简体   繁体   English

使用 LINQ 对时间戳列表中的重复项进行排序、舍入和删除

[英]Sorting, rounding and removing duplicates in a list of time stamps using LINQ

I'm trying to process some data based on their time stamps.我正在尝试根据它们的时间戳处理一些数据。 I have a working solution, but I feel that it could be expressed in a much cleaner way using LINQ.我有一个可行的解决方案,但我觉得它可以使用 LINQ 以更简洁的方式表达。

I need to do the following:我需要执行以下操作:

  1. Sort the list, based on the timestamp根据时间戳对列表进行排序
  2. Round off the milliseconds四舍五入毫秒
  3. Remove any duplicate values (does not matter which is removed)删除任何重复值(删除哪个无关紧要)

Here is my current working solution:这是我目前的工作解决方案:

using MoreLinq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SortingWITSMLRealTimeSignals
{
    class Program
    {
        class Foo
        {
            public DateTime TimeStampUtc;
            public int SomeData;
        }

        static void Main(string[] args)
        {
            List<Foo> testData = new List<Foo> { 
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 23, 515), SomeData = 42 },
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 24, 515), SomeData = 42 },
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 25, 515), SomeData = 42 },
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 25, 245), SomeData = 33 },
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 27, 515), SomeData = 42 },
                new Foo { TimeStampUtc = new DateTime(2019, 11, 12, 20, 20, 28, 515), SomeData = 42 },
            };

            List<Foo> orderedTestData = testData.OrderBy(rs => rs.TimeStampUtc).ToList();

            List<Foo> roundedTestData = new List<Foo>();
            foreach (var otd in orderedTestData)
            {
                otd.TimeStampUtc = otd.TimeStampUtc.AddMilliseconds(-otd.TimeStampUtc.Millisecond);
                roundedTestData.Add(otd);
            }

            var filteredTestData = roundedTestData.DistinctBy(x => x.TimeStampUtc).ToList();
        }
    }
}

This works:这有效:

var result =
    testData
        .GroupBy(otd => otd.TimeStampUtc.AddMilliseconds(-otd.TimeStampUtc.Millisecond))
        .SelectMany(x => x.Take(1))
        .ToList();

From your source data, I get:从您的源数据中,我得到:

结果

You could also try this LINQ query:你也可以试试这个 LINQ 查询:

var result = testData
    .Select(td => new Foo
    {
        TimeStampUtc = td.TimeStampUtc.AddMilliseconds(-td.TimeStampUtc.Millisecond),
        SomeData = td.SomeData
    })
    .OrderBy(td => td.TimeStampUtc)
    .DistinctBy(otd => otd.TimeStampUtc)
    .ToList();

Since we want the final collection to be sorted, putting the OrderBy last here is a good idea.由于我们希望对最终集合进行排序,因此将OrderBy放在最后是一个好主意。 Also sorting on the the unique values returned from DistinctBy instead of all the items will yield better performance for larger sets.此外,对从DistinctBy返回的唯一值而不是所有项目进行排序将为更大的集合产生更好的性能。 There is also no guarantee that DistinctBy will return items in order, so sorting last is a good idea.也不能保证DistinctBy会按顺序返回项目,因此排序最后是一个好主意。 Following the SELECT, DISTINCT and ORDERBY order of statements is recommended with SQL queries anyways, so applying the same logic to LINQ makes sense.无论如何,SQL 查询都建议遵循 SELECT、DISTINCT 和 ORDERBY 语句的顺序,因此将相同的逻辑应用于 LINQ 是有意义的。

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

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