开发者

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜