Reputation: 331
I have a list of list of object that I try to group by one of the list of object.
I tried the following code but it is not grouping anything
I have a list of type myObj like [obj1[],obj2[],obj3[],obj4[]]
I tried
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();
but it outputs the same as myObj
e.g.
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]},
]
I want the output :
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]},
]
Upvotes: 0
Views: 99
Reputation: 8596
You need a custom comparer, see link @mjwills posted.
Custom comparer example:
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;
}
}
Add this custom comparer to the GroupBy and your original code now works as you expected:
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();
Upvotes: 2
Reputation: 1238
In any case the problem is your KeySelector. the key you select is "a => new { a.obj1 }". So for every item you create a new instance of the key. Since there is no equality comparer overload the only comparision is reference equal. The key-selector has to return instances, where the GroupBy method can perform "==" operation and realy gets the same value.
I cannot reproduce your sample, so i cannot verify if this is the only issue, but in any case your KeySelector should be: a => a.obj1
and of course you have to change the first assignment in your Select-Statement to obj1= x.Key,
Upvotes: 0