2

我有这个对象:

notes:[ 
     { user: {
           name: "A",
           group:{
                id:1,
                name:"Group 1"
           }
     }, 
     { user: {
           name: "B",
           group:{
                id:1,
                name:"Group 1"
           }
    }]

我需要按组分组..所以我尝试了这个:

foreach (IGrouping<Group, Note> item in notes.GroupBy(n => n.User.Group))
{
    var groupName = item.Key.Name;

    foreach (var note in item)
    {
        //
    }
}

但是我遇到了一个问题,因为分组不起作用(我认为这是因为它使用引用来分组复杂类型)。如果我n.User.Group通过n.User.GroupId它进行更改,但如果我这样做,我将无法获得组名。

4

4 回答 4

3

您需要在 Group 类中覆盖 Equals 和 GetHashCode。R# 为其生成这种代码:

public class Group
{
    public int GroupId { get; set; }
    public string Name { get; set; }

    protected bool Equals(Group other)
    {
        return GroupId == other.GroupId;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Group) obj);
    }

    public override int GetHashCode()
    {
        return GroupId;
    }
}
于 2013-01-21T13:12:45.110 回答
3

是的,这是正确的。默认情况下,类都是唯一的,但是您可以覆盖唯一性。

  1. 在组对象上覆盖Equals(object obj)&GetHasCode()以实现您自己的相等性
  2. 实现IEqualityComparer<Group>并将其作为第三个参数传递给 GroupBy 方法。
于 2013-01-21T13:12:59.883 回答
1

您在这里有几个选择:

  • 确保组对象的类实现 GetHashCode 和 Equals。实现这些可以像比较组内的 id 一样简单
  • 按 id 分组,并从分组中第一个用户的组中获取组名。所有分组的用户属于同一个组,因此名称将相同
  • 如果您无权访问您的组类的源,请根据其包装的组的 id 实现 GetHashCode 和 Equals 的包装器进行分组。
于 2013-01-21T13:14:17.690 回答
0

您利用比较匿名类的优势并写为

notes.GroupBy(n => new{n.User.Group.ID,n.User.Group.Name});
于 2013-01-21T13:16:50.153 回答