Transform a collection
.net, c#, linq
Solution
Given these simplistic classes:
class C {
public int A;
public int B;
}
class R {
public int A;
public List<int> Bs = new List<int>();
}
You can do it like this:
var cs = new C[] {
new C() { A = 1, B = 1 },
new C() { A = 1, B = 2 },
new C() { A = 2, B = 3 },
new C() { A = 2, B = 4 },
new C() { A = 1, B = 5 },
new C() { A = 3, B = 6 }
};
var rs = cs.
OrderBy(o => o.B).
ThenBy(o => o.A).
Aggregate(new List<R>(), (l, o) => {
if (l.Count > 0 && l.Last().A == o.A) {
l.Last().Bs.Add(o.B);
}
else {
l.Add(new R { A = o.A, Bs = { o.B } });
}
return l;
});
Note: In the above I assume that the Bs and then the As have to be sorted. If that's not the case, it's a simple matter of removing the sorting instructions:
var rs = cs.
Aggregate(new List<R>(), (l, o) => {
if (l.Count > 0 && l.Last().A == o.A) {
l.Last().Bs.Add(o.B);
}
else {
l.Add(new R { A = o.A, Bs = { o.B } });
}
return l;
});
Problem
Have a collection of objects. Schematically: ``` [ { A = 1, B = 1 } { A = 1, B = 2 } { A = 2, B = 3 } { A = 2, B = 4 } { A = 1, B = 5 } { A = 3, B = 6 } ] ``` Need: ``` [ { A = 1, Bs = [ 1, 2 ] } { A = 2, Bs = [ 3, 4 ] } { A = 1, Bs = [ 5 ] } { A = 3, Bs = [ 6 ] } ] ``` Is it possible to LINQ such? Note: Ordering is important. So `Bs = [5]` can't be merged with `Bs = [1, 2]`