【问题标题】:C# - group list by TimeSpan starting from specific start pointC# - 从特定起点开始按 TimeSpan 分组列表
【发布时间】:2013-01-28 09:37:08
【问题描述】:

我想按时间步长(小时、天、周等)对列表进行分组,并计算每个组的总和,但从特定时间开始。

现在我有了输入列表:

TIME    VALUE
11:30   2
11:50   2
12:00   6
12:30   10
12:50   2

小时步长

var timeStep=new TimeSpan(1,0,0);

我正在用这样的东西对我的列表进行分组

var myList = list.GroupBy(x =>
            {
                return x.Time.Ticks / timeStep.Ticks;
            })
            .Select(g => new { Time = new DateTime(g.Key * timeStep.Ticks), Value = g.Sum(x => x.Value) }).ToList();

它工作正常(也适用于任何其他步骤,例如每天、每周)并给出结果:

TIME    SUM
11:00   4
12:00   18

但现在我必须按小时步长对列表进行分组,但从例如开始。每小时 30 分钟,所以我该怎么做才能拥有这样的东西:

TIME    SUM
11:30   10
12:30   12

【问题讨论】:

    标签: c# linq list grouping timespan


    【解决方案1】:

    最好使用自定义 DateTme 比较器:

    internal class DateTimeComparer : IEqualityComparer<DateTime>
    {
        public bool Equals(DateTime x, DateTime y)
        {
            return GetHashCode(x) == GetHashCode(y);  
            // In general, this shouldn't be written (because GetHashCode(x) can equal GetHashCode(y) even if x != y (with the given  comparer)). 
            // But here, we have: x == y <=> GetHashCode(x) == GetHashCode(y)
        }
    
        public int GetHashCode(DateTime obj)
        {
            return (int)((obj - new TimeSpan(0, 30, 0)).Ticks / new TimeSpan(1, 0, 0).Ticks);
        }
    }
    

    与:

    var myList = list.GroupBy(x => x.Time, new DateTimeComparer())
                     .Select(g => new { Time = g.Key, Value = g.Sum(x => x.Value) }).ToList();
    

    【讨论】:

    • 谢谢,它有效 :) 如果我想按月分组列表,但也有一个特定的开始日期(例如,每月 10 日,所以我将从 1 月 10 日到2 月 10 日等)?顺便说一句,这个 DateTimeComparer 不是工作 N * N 次吗?效率高吗?
    • 不,DateTimeComparer 不起作用 N * N 次。这就是方法分组的力量。这些项目存储在一种以 GetHashCode 为键的字典中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多