Linq: Convert list of object to dictionary, with an object member as value
I have a class like:
public class ContainerClass
{
public guid Group { get; set; }
public int Value { get; set; }
}
c开发者_如何学JAVAontained in:
IEnumerable<ContainerClass>
How do I convert it to the following dictionary?
Dictionary<guid, List<int>>
I've looked at similar questions (eg.
Create a dictionary on a list with grouping) but that goes to Dictionary<guid, List<ContainerClass>>
which is different from what I'd like.
I know I can do a secondary linq query to just get the value entries after I have an IEnumerable but that seems messy; it seems like there should be a way to do this directly in a single statement.
Edit: Note, I'm aware of Lookup(), but in this case, I am actually doing bulk processing by Group, so I really do need the Dictionary (or something where each group has a collection of Values). In this case, each Group is being sent to a resource, and I want to send all the values for that resource in bulk: if I have 10 groups, with 50 values each (500 entries in my List total), I want to make 10 calls.
Rather than a Dictionary<Guid, List<int>>
could you use a Lookup<Guid, int>
? That would make it easy:
var lookup = list.ToLookup(x => x.Group, x => x.Value);
A Lookup
is much like a Dictionary
, but designed to work with multiple values per key. On interesting difference is that if you fetch a missing key, you'll just get an empty sequence back instead of an exception.
If you can use that, that's great. Otherwise you could always convert from a Lookup
to a Dictionary
:
var dictionary = list.ToLookup(x => x.Group, x => x.Value)
.ToDictionary(x => x.Key, x => x.Value.ToList());
I'm assuming you have multiple instances of the class, otherwise it is trivial. In LINQ, something similar is:
var lookup = data.ToLookup(obj => obj.Group, obj => obj.Value);
Then you can, for example:
foreach(var value in lookup[someGuid]) {
...
}
If you really need this as a dictionary (rather than a lookup, which is close):
var lookup = data.GroupBy(obj => obj.Group).ToDictionary(
grp => grp.Key, grp => grp.Select(obj => obj.Value).ToList());
Given an IEnumerable<ContainerClass> named objects
, you could do this:
var dict = objects
.ToLookup(o => o.Group)
.ToDictionary(grp => grp.Key, grp => grp.Select(o => o.Value).ToList());
Explanation:
ToLookup
method converts the IEnumerable<ContainerClass>
to an ILookup<Guid, ContainerClass>
. The ToDictionary
method then takes the collection of IGrouping<Guid, ContainerClass>
objects, and selects the Key
of the grouping as the key for the dictionary, and then selects the Value
property of the ContainerClass
objects, and converts that to a List<int>
for the dictionary values.
You may not actually need a Dictionary<ContainerClass>
. If you're OK with using an ILookup<Guid, int>
instead, you can just do this:
var lookup = objects.ToLookup(o => o.Group, o => o.Value);
精彩评论