按 x 秒范围内的值对时间跨度列表进行分组



我在列表中有以下值:

[0] {-00:00:14.7100000} System.TimeSpan
[1] {-00:00:14.7000000} System.TimeSpan
[2] {-00:00:14.6900000} System.TimeSpan
[3] {-00:00:15.2000000} System.TimeSpan
[4] {-00:00:00.1300000} System.TimeSpan
[5] {-00:00:00.1200000} System.TimeSpan
[6] {-00:00:00.1000000} System.TimeSpan
[7] {-00:00:00.0900000} System.TimeSpan

现在,我想按以下方式对这些值进行分组。第 1 组:

[0] {-00:00:14.7100000} System.TimeSpan
[1] {-00:00:14.7000000} System.TimeSpan
[2] {-00:00:14.6900000} System.TimeSpan
[3] {-00:00:15.2000000} System.TimeSpan

和第 2 组:

[0] {-00:00:00.1300000} System.TimeSpan
[1] {-00:00:00.1200000} System.TimeSpan
[2] {-00:00:00.1000000} System.TimeSpan
[3] {-00:00:00.0900000} System.TimeSpan

这样我以后就可以构建平均数并得到:-14.826-0.11

我会选择列表的第一个元素并查找该值的范围 x(在我的情况下 3 秒应该没问题(范围内的任何值。然后我删除旧列表中的匹配项并将其添加到新列表中。我想我必须使用嵌套的"for 循环",但我只是不知道具体如何。你会怎么做?

编辑:列表中的值是随机的。这意味着事先定义组不会完成这项工作。我扩展了示例列表。

编辑2:Tim S.的答案对我有用。谢谢。

您可以通过一个简单的while循环和一些 LINQ 来实现此目的。我还使用yield return使代码可读。

private static readonly TimeSpan GapSize = TimeSpan.FromSeconds(3);
public static IEnumerable<IEnumerable<TimeSpan>> GetGroups(IEnumerable<TimeSpan> timespans)
{
    var timespansList = timespans.ToList();
    while (timespansList.Count > 0)
    {
        TimeSpan min = timespansList.Min();
        var closeList = timespansList.Where(t => t - min <= GapSize).ToList();
        yield return closeList;
        foreach (var timeSpan in closeList)
        {
            timespansList.Remove(timeSpan);
        }
    }
}

您可能还想在返回之前对结果进行排序(它们在每个组中保留原始顺序;组从低到高(。如果性能是一个问题,那么肯定有更有效的方法来编写代码,但这将完成工作!

最新更新