Reputation: 14584
I have an object that looks like this:
class Model
{
public string Category {get;set;}
public string Description {get;set;}
}
Currently I am getting the whole list of those objects with Linq, and then manually setting up a dictionary, like this:
List<Model> models = //get list from repository and then with linq order them by category and description
Dictionary<string, List<Model>> dict= new Dictionary<string, List<Model>>();
foreach (var m in models) {
if (dict.ContainsKey(m.Category))
{
dict[m.Category].Add(m);
}
else
{
dict.Add(m.Category, new List<Model> { m });
}
}
this way I can access all of the models of a certain category by using the keys.
Is there a way to generate the dictionary straight with a LINQ query?
Thanks!
Upvotes: 1
Views: 7355
Reputation: 40150
Have you seen the Lookup
class? (msdn)
You can create it with a call to the Enumerable.ToLookup() method (msdn)
It's basically exactly what you want here, and handles the dupe keys.
Upvotes: 6
Reputation: 71573
You can use Aggregate() to hide the foreach logic, but as the OP to whom I last suggested that said, it's a loop in Linq clothing.
What about:
var myDictionary = (from m in models
group m by m.Category into theGroup
select new {Key = m.Category, Value = theGroup.ToList()))
.ToDictionary(x=>x.Key, x=>x.Value);
Upvotes: 0
Reputation: 21615
yeah there's a way to that, but to get this done you'll need to group them first (to avoid duplicate keys):
var dict = (from model in models
group model by model.Category into g
select g).ToDictionary(x => x.Key, x => x.ToList());
(While you're at it, I wonder what the performance of this and the .ContainsKey() way is)
Upvotes: 5