猿问

按日期时间间隔分组对象

我有一个用户列表和他们的注册日期。现在我想按用户的注册日期以 5 分钟为间隔对用户进行分组,如下所示:


Group 1

15:01

15:03

15:04


Group 2

15:06

15:06


Group 3

15:17


Group 4

15:59

我的问题是:为什么这个解决方案给了我正确的答案:


var users = GetUsers();

var interval = 5;


var registerInvervals = users.GroupBy(x => new

    {

        Month = x.Registered.Month,

        Day = x.Registered.Day,

        Hour = x.Registered.Hour,

        MinuteFrom = (x.Registered.Minute/interval)*interval,

        MinuteTo = (((x.Registered.Minute / interval) * interval) + 5)%61

    })

    .ToList();

但这不是:


var users = GetUsers();

var interval = 5;


var registerInvervals = users.GroupBy(x => new GroupCriteria()

    {

        Month = x.Registered.Month,

        Day = x.Registered.Day,

        Hour = x.Registered.Hour,

        MinuteFrom = (x.Registered.Minute/interval)*interval,

        MinuteTo = (((x.Registered.Minute / interval) * interval) + 5)%61

    })

    .ToList();


class GroupCriteria

{

    public int Month { get; set; }

    public int Day { get; set; }

    public int Hour { get; set; }

    public int MinuteFrom { get; set; }

    public int MinuteTo { get; set; }

}

第二种解决方案返回 7 个组,每个组有 1 个用户。


holdtom
浏览 174回答 2
2回答

MMTTMM

那是因为您没有覆盖Equals和GetHashCode为您的GroupCriteria班级。当调用GroupBy项目通过共享相同的密钥进行分组时。在指定的情况下,键是您创建的对象,相等是由为该实例定义的相等。这样做时,GroupCriteria它会通过默认定义的对象(它们的引用)检查对象的相等性。当您为每个项目投影一个新对象时,引用是不同的,并且组属于单个项目。至于匿名对象 ( new {...}),equals 比较字段并因此起作用。有关此行为的更多信息,您可以阅读为什么匿名类型的 Equals 实现会比较字段? .正如格特在该问题中的回答所述:匿名类型的 Equals 和 GetHashcode 方法覆盖从 object 继承的方法,并根据属性的 Equals 和 GetHashcode 定义,因此当且仅当它们的所有属性都相等时,相同匿名类型的两个实例才相等。

明月笑刀无情

创建的实例通过相等性进行比较。对于第一个示例中的匿名类型,如果字段为,则实例相等,但在第二个示例中,相等是通过引用,因此具有相同属性值的两个实例不被视为相等,因此最终位于不同的组中。
随时随地看视频慕课网APP
我要回答