【问题标题】:Group a list by a list of object按对象列表对列表进行分组
【发布时间】:2019-02-12 09:01:17
【问题描述】:

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

我尝试了以下代码,但它没有对任何内容进行分组

我有一个 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]},
]

【问题讨论】:

标签: c# linq


【解决方案1】:

您需要一个自定义比较器,请参阅发布的链接 @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();

【讨论】:

  • 我做了类似的事情,它按我的预期工作。 @mjwills 链接帮助我理解了为什么需要做一个自定义比较器。非常感谢!
【解决方案2】:

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

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

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

【讨论】:

猜你喜欢
  • 2022-01-21
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
相关资源
最近更新 更多