I realized that I didn\'t give enough information for most people to read my mind and understand all my needs, so I changed this somewhat from the original.
An elegant way would be to not create the dictionaries yourself but use LINQ GroupBy
and ToDictionary
to generate it for you.
var things = new[] {
new Thing { Foo = 1, Bar = 2, Baz = "ONETWO!" },
new Thing { Foo = 1, Bar = 3, Baz = "ONETHREE!" },
new Thing { Foo = 1, Bar = 2, Baz = "ONETWO!" }
}.ToList();
var bazGroups = things
.GroupBy(t => t.Foo)
.ToDictionary(gFoo => gFoo.Key, gFoo => gFoo
.GroupBy(t => t.Bar)
.ToDictionary(gBar => gBar.Key, gBar => gBar.First().Baz));
Debug.Fail("Inspect the bazGroups variable.");
I assume that by categorizing Baz
using Foo
and Bar
you mean that if two things have both Foo
and Bar
equals then their Baz
value also be the same as well. Please correct me if I'm wrong.
You're basically group by the Foo
property first...
then for each resulting group, you group on the Bar
property...
then for each resulting group you take the first Baz
value as the dictionary value.
If you noticed, the method names matched exactly what you are trying to do. :-)
EDIT: Here's another way using query comprehensions, they are longer but are quiet easier to read and grok:
var bazGroups =
(from t1 in things
group t1 by t1.Foo into gFoo
select new
{
Key = gFoo.Key,
Value = (from t2 in gFoo
group t2 by t2.Bar into gBar
select gBar)
.ToDictionary(g => g.Key, g => g.First().Baz)
})
.ToDictionary(g => g.Key, g => g.Value);
Unfortunately, there are no query comprehension counterpart for ToDictionary so it's not as elegant as the lambda expressions.
...
Hope this helps.