C# 在LINQ中对集合进行GroupBySubElement的简单方法?

C# 在LINQ中对集合进行GroupBySubElement的简单方法?,c#,linq,C#,Linq,我对可枚举项执行了常规GroupBy操作: e.GroupBy(i => i.Property) 但是,如果i.Property真的是一个集合,我将如何分解集合并使用列表的元素作为分组键 例如,假设我有两个对象(Z,Y),每个对象都有一个列表: Z: { List = { A, B, C }} Y: { List = { B, C, D }} 现在运行GroupBySubelement(o=>o.List)不会按列表本身分组,而是迭代列表并生成以下分组 {A, {Z}} {B, {Z,

我对可枚举项执行了常规GroupBy操作:

e.GroupBy(i => i.Property)
但是,如果i.Property真的是一个集合,我将如何分解集合并使用列表的元素作为分组键

例如,假设我有两个对象(Z,Y),每个对象都有一个列表:

Z: { List = { A, B, C }}
Y: { List = { B, C, D }}
现在运行GroupBySubelement(o=>o.List)不会按列表本身分组,而是迭代列表并生成以下分组

{A, {Z}}
{B, {Z, Y}}
{C, {Z, Y}}
{D, {Y}
这可能吗

谢谢

这样做可以:

var combinations = e.SelectMany(i => i.List.Select(x => new { x, i }));
var groups = combinations.GroupBy(c => c.x, c => c.i);

下面是一些实现所需功能的示例代码:

//This is just temporary data.  Has the similar structure to what you want.
var parts = new[]
                {
                    new
                        {
                            Name = "X",
                            Property = new[] {'A', 'B', 'C'}
                        },
                    new
                        {
                            Name = "Y",
                            Property = new[] {'B', 'C', 'D'}
                        },
                    new
                        {
                            Name = "Z",
                            Property = new char[] { }
                        }
                    };

var groupedBySub = from part in parts
                   from sub in part.Property
                   group part by sub;

foreach(var group in groupedBySub)
{
    Console.WriteLine("{0} - {1}", group.Key, string.Join(", ", group.Select(x => x.Name)));
}
哪些产出:

A - X
B - X, Y
C - X, Y
D - Y
您还可以通过方法链方式实现这一点:

var groupedBySub = parts.SelectMany(part => part.Property, (part, sub) => new {part, sub}).GroupBy(t => t.sub,  t => t.part);
如果要在列表为空的情况下捕获它:

var groupedBySub = from part in parts
                   from sub in part.Property.DefaultIfEmpty()
                   group part by sub;
当替换上述代码时,输出:

A - X
B - X, Y
C - X, Y
D - Y
  - Z

这里的部分问题是您没有良好的数据结构:

var z = new List<T>(); // I'm using T here, so let's pretend this is in a generic method
var y = new List<T>();
// add a bunch of stuff

这会捕获列表为空的情况吗?但在这种情况下,您想要什么?具有空密钥的组?这似乎有效;我缺少的部分是使用SelectMany和DefaultIfEmpty子句的替代方法。谢谢
var allOfTheLists = new Dictionary<T, List<T>>();
var explodedList = allOfTheLists.SelectMany((pair) => pair.Value.Select((item) => new { pair.Key, item}));
var grouping = explodedList.GroupBy((explodedItem) => explodedItem.item);