简体   繁体   中英

Can I use an anonymous type for this Linq grouping?

I have the following code which produces a dictionary containing multiple lists; each list can be retrieved with a numeric key.

public class myClass
{
    public string Group { get; set; }
    public int GroupIndex { get; set; }
    ...
}

public List<MyClass> myList { get; set; }

private Class IndexedGroup
{
    public int Index { get; set; }
    public IEnumerable<MyClass> Children { get; set; }
}

public Dictionary<int, IEnumerable<MyClass>> GetIndexedGroups(string group)
{
    return myList.Where(a => a.Group == group)
                 .GroupBy(n => n.GroupIndex)
                 .Select(g => new IndexedGroup { Index = g.Key, Children = g })
                 .ToDictionary(key => key.Index, value => value.Children);
}

Is there any way to eliminate the IndexedGroup class?

I've tried using an anonymous type in the Select method, like this:

.Select(g => new { Index = g.Key, Children = g })

but I get a type conversion error.

Cast Children from IGrouping<T> to IEnumerable<T> , or explicitly pass generic parameters to the ToDictionary call.

The g parameter is an IGrouping<T> , which implements IEnumerable<T> .
The implicit generic calls end up creating a Dictionary<int, IGrouping <MyClass>> , which cannot be converted to a Dictionary<int, IEnumerable <MyClass>> .

This is avoided by your IndexedGroup class, since its Children property explicitly typed as IEnumerable<MyClass> .

For example:

 
 
 
  
  return myList.Where(a => a.Group == group) .GroupBy(n => n.GroupIndex) .ToDictionary<int, IEnumerable<MyClass>>(g => g.Key, g => g);
 
  

Also, you may be interested in the ILookup<TKey, TElement> interface .

You could just get rid of the Select() entirely and call .AsEnumerable() :

return myList.Where(a => a.Group == group)
             .GroupBy(n => n.GroupIndex)
             .ToDictionary(g => g.Key, g => g.AsEnumerable());

Or you could change your return type to an ILookup , which is basically the data structure you're going for:

public ILookup<int, MyClass> GetIndexedGroups(string group)
{
    return myList.Where(a => a.Group == group)
                .ToLookup(n => n.GroupIndex);                    
}

How about the following?

return myList.Where(a => a.Group == group)
             .GroupBy(n => n.GroupIndex)
             .ToDictionary(g => g.Key, g => g as IEnumerable<MyClass>);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM