按对象列表对列表进行分组

时间:2019-02-12 09:01:17

标签: c# linq

我有一个对象列表列表,我尝试按对象列表之一进行分组。

我尝试了以下代码,但未将任何内容分组

我有一个myObj类型的列表,例如[obj1 [],obj2 [],obj3 [],obj4 []]

我尝试了

 myObj.GroupBy(
            a => new { a.obj1},
            a => new { a.obj2, a.obj3, a.obj4})
            .Select(x => new myObj 
            {
                obj1= x.Key.obj1,
                obj2= x.SelectMany(l => l.obj2).Distinct().ToList(),
                obj3= x.SelectMany(list => list.obj3).Distinct().ToList(),
                obj4= x.SelectMany(list => list.obj4).Distinct().ToList(),
            }
            )
            .ToList();

但其输出与myObj相同

例如

myObj = [
 {[a1],[a2,b2,c2],[e2],[f4,g4]},
 {[a1],[d2,e2],[e3],[f4]},
 {[a2,a1],[d2,e2],[e3],[f4]},
 {[a2],[d2,e2],[e3],[f4,g4]},
 {[a2],[a2,d2,e2],[e3,f3],[f4]},
 ]

我想要输出:

myGroupedObj = [
{[a1],[a2,b2,c2,d2,e2],[e2,e3],[f4,g4]},
{[a2,a1],[d2,e2],[e3],[f4]},
{[a2],[a2,d2,e2],[e3,f3],[f4,g4]},
]

2 个答案:

答案 0 :(得分:2)

您需要一个自定义比较器,请参阅链接@mjwills。

自定义比较器示例:

public class ListComparer : IEqualityComparer<List<object>>
{
    public bool Equals(List<object> a, List<object> b)
    {
        if (a.Count != b.Count)
            return false;
        for (int i = 0; i < a.Count; i++)
            if (a[i] != b[i]) 
                return false;
        return true;
    }

    public int GetHashCode(List<object> list)
    {
        var hash = 0;
        foreach (var item in list)
        {
            hash = hash ^ item.GetHashCode();
        }
        return hash;
    }
}

将此自定义比较器添加到GroupBy,您的原始代码现在可以按预期工作:

myObjs
    .GroupBy(a => a.obj1, new ListComparer())
    .Select(x => new myObj
    {
    obj1 = x.Key,
    obj2 = x.SelectMany(l => l.obj2).Distinct().ToList(),
    obj3 = x.SelectMany(list => list.obj3).Distinct().ToList(),
    obj4 = x.SelectMany(list => list.obj4).Distinct().ToList(),
    })
    .ToList();

答案 1 :(得分:0)

无论如何,问题出在您的KeySelector。 您选择的键是“ a => new {a.obj1}”。因此,为每个项目创建密钥的新实例。由于没有相等比较器重载,因此唯一的比较是参考相等。 键选择器必须返回实例,在这些实例中,GroupBy方法可以执行“ ==”操作,并且realy获得相同的值。

我无法复制您的示例,因此无法验证这是否是唯一的问题,但是无论如何,您的KeySelector应该是:a => a.obj1

当然,您必须将Select-Statement中的第一个分配更改为obj1= x.Key,